# confection

> The sweetest config system for Python

- **URL**: https://www.freshcrate.ai/projects/confection
- **Author**: Explosion
- **Category**: RAG & Memory
- **Latest version**: `1.3.3` (2026-04-21)
- **License**: MIT
- **Source**: https://github.com/explosion/confection
- **Language**: Python
- **GitHub**: 194 stars, 15 forks
- **Registry**: pypi (`confection`)
- **Tags**: `pypi`

## Description

<a href="https://explosion.ai"><img src="https://explosion.ai/assets/img/logo.svg" width="125" height="125" align="right" /></a>

# Confection: The sweetest config system for Python

`confection` :candy: is a lightweight library that offers a **configuration
system** letting you conveniently describe arbitrary trees of objects.

Configuration is a huge challenge for machine-learning code because you may want
to expose almost any detail of any function as a hyperparameter. The setting you
want to expose might be arbitrarily far down in your call stack, so it might
need to pass all the way through the CLI or REST API, through any number of
intermediate functions, affecting the interface of everything along the way. And
then once those settings are added, they become hard to remove later. Default
values also become hard to change without breaking backwards compatibility.

To solve this problem, `confection` offers a config system that lets you easily
describe arbitrary trees of objects. The objects can be created via function
calls you register using a simple decorator syntax. You can even version the
functions you create, allowing you to make improvements without breaking
backwards compatibility. The most similar config system we’re aware of is
[Gin](https://github.com/google/gin-config), which uses a similar syntax, and
also allows you to link the configuration system to functions in your code using
a decorator. `confection`'s config system is simpler and emphasizes a different
workflow via a subset of Gin’s functionality.

[![tests](https://github.com/explosion/confection/actions/workflows/tests.yml/badge.svg)](https://github.com/explosion/confection/actions/workflows/tests.yml)
[![Current Release Version](https://img.shields.io/github/v/release/explosion/confection.svg?style=flat-square&include_prereleases&logo=github)](https://github.com/explosion/confection/releases)
[![pypi Version](https://img.shields.io/pypi/v/confection.svg?style=flat-square&logo=pypi&logoColor=white)](https://pypi.org/project/confection/)
[![conda Version](https://img.shields.io/conda/vn/conda-forge/confection.svg?style=flat-square&logo=conda-forge&logoColor=white)](https://anaconda.org/conda-forge/confection)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/ambv/black)

## ⏳ Installation

```bash
pip install confection
```

```bash
conda install -c conda-forge confection
```

## 👩‍💻 Usage

The configuration system parses a `.cfg` file like

```ini
[training]
patience = 10
dropout = 0.2
use_vectors = false

[training.logging]
level = "INFO"

[nlp]
# This uses the value of training.use_vectors
use_vectors = ${training.use_vectors}
lang = "en"
```

and resolves it to a `Dict`:

```json
{
  "training": {
    "patience": 10,
    "dropout": 0.2,
    "use_vectors": false,
    "logging": {
      "level": "INFO"
    }
  },
  "nlp": {
    "use_vectors": false,
    "lang": "en"
  }
}
```

The config is divided into sections, with the section name in square brackets –
for example, `[training]`. Within the sections, config values can be assigned to
keys using `=`. Values can also be referenced from other sections using the dot
notation and placeholders indicated by the dollar sign and curly braces. For
example, `${training.use_vectors}` will receive the value of use_vectors in the
training block. This is useful for settings that are shared across components.

The config format has three main differences from Python’s built-in
`configparser`:

1. JSON-formatted values. `confection` passes all values through `json.loads` to
   interpret them. You can use atomic values like strings, floats, integers or
   booleans, or you can use complex objects such as lists or maps.
2. Structured sections. `confection` uses a dot notation to build nested
   sections. If you have a section named `[section.subsection]`, `confection`
   will parse that into a nested structure, placing subsection within section.
3. References to registry functions. If a key starts with `@`, `confection` will
   interpret its value as the name of a function registry, load the function
   registered for that name and pass in the rest of the block as arguments. If
   type hints are available on the function, the argument values (and return
   value of the function) will be validated against them. This lets you express
   complex configurations, like a training pipeline where `batch_size` is
   populated by a function that yields floats.

There’s no pre-defined scheme you have to follow; how you set up the top-level
sections is up to you. At the end of it, you’ll receive a dictionary with the
values that you can use in your script – whether it’s complete initialized
functions, or just basic settings.

For instance, let’s say you want to define a new optimizer. You'd define its
arguments in `config.cfg` like so:

```ini
[optimizer]
@optimizers = "my_cool_optimizer.v1"
learn_rate = 0.001
gamma = 1e-8
```

To load and

## Recent releases

| Version | Date | Urgency | Changes |
| --- | --- | --- | --- |
| `1.3.3` | 2026-04-21 | Low | Imported from PyPI (1.3.3) |
| `release-v1.3.3` | 2026-03-24 | Medium | Config values True, False, and None (Python-style capitalised literals)     were silently kept as strings rather than being converted to their Python     types. This went unnoticed in older releases because pydantic v1's     parse_obj coerced the strings during validation. With the new built-in     type checker (which correctly requires actual bools), configs using the     capitalised forms broke.  Handle True/False/None in try_load_json as aliases for the JSON-style     true/false/null |
| `release-v1.3.3` | 2026-03-24 | Low | Config values True, False, and None (Python-style capitalised literals)     were silently kept as strings rather than being converted to their Python     types. This went unnoticed in older releases because pydantic v1's     parse_obj coerced the strings during validation. With the new built-in     type checker (which correctly requires actual bools), configs using the     capitalised forms broke.  Handle True/False/None in try_load_json as aliases for the JSON-style     true/false/null |
| `release-v1.3.3` | 2026-03-24 | Low | Config values True, False, and None (Python-style capitalised literals)     were silently kept as strings rather than being converted to their Python     types. This went unnoticed in older releases because pydantic v1's     parse_obj coerced the strings during validation. With the new built-in     type checker (which correctly requires actual bools), configs using the     capitalised forms broke.  Handle True/False/None in try_load_json as aliases for the JSON-style     true/false/null |
| `release-v1.3.3` | 2026-03-24 | Low | Config values True, False, and None (Python-style capitalised literals)     were silently kept as strings rather than being converted to their Python     types. This went unnoticed in older releases because pydantic v1's     parse_obj coerced the strings during validation. With the new built-in     type checker (which correctly requires actual bools), configs using the     capitalised forms broke.  Handle True/False/None in try_load_json as aliases for the JSON-style     true/false/null |
| `release-v1.3.3` | 2026-03-24 | Low | Config values True, False, and None (Python-style capitalised literals)     were silently kept as strings rather than being converted to their Python     types. This went unnoticed in older releases because pydantic v1's     parse_obj coerced the strings during validation. With the new built-in     type checker (which correctly requires actual bools), configs using the     capitalised forms broke.  Handle True/False/None in try_load_json as aliases for the JSON-style     true/false/null |
| `release-v1.3.3` | 2026-03-24 | Low | Config values True, False, and None (Python-style capitalised literals)     were silently kept as strings rather than being converted to their Python     types. This went unnoticed in older releases because pydantic v1's     parse_obj coerced the strings during validation. With the new built-in     type checker (which correctly requires actual bools), configs using the     capitalised forms broke.  Handle True/False/None in try_load_json as aliases for the JSON-style     true/false/null |
| `release-v1.3.3` | 2026-03-24 | Low | Config values True, False, and None (Python-style capitalised literals)     were silently kept as strings rather than being converted to their Python     types. This went unnoticed in older releases because pydantic v1's     parse_obj coerced the strings during validation. With the new built-in     type checker (which correctly requires actual bools), configs using the     capitalised forms broke.  Handle True/False/None in try_load_json as aliases for the JSON-style     true/false/null |
| `release-v1.3.3` | 2026-03-24 | Low | Config values True, False, and None (Python-style capitalised literals)     were silently kept as strings rather than being converted to their Python     types. This went unnoticed in older releases because pydantic v1's     parse_obj coerced the strings during validation. With the new built-in     type checker (which correctly requires actual bools), configs using the     capitalised forms broke.  Handle True/False/None in try_load_json as aliases for the JSON-style     true/false/null |
| `release-v1.3.3` | 2026-03-24 | Low | Config values True, False, and None (Python-style capitalised literals)     were silently kept as strings rather than being converted to their Python     types. This went unnoticed in older releases because pydantic v1's     parse_obj coerced the strings during validation. With the new built-in     type checker (which correctly requires actual bools), configs using the     capitalised forms broke.  Handle True/False/None in try_load_json as aliases for the JSON-style     true/false/null |

## Citation

- HTML: https://www.freshcrate.ai/projects/confection
- Markdown: https://www.freshcrate.ai/projects/confection.md
- Dependencies JSON: https://www.freshcrate.ai/api/projects/confection/deps

_Generated by freshcrate.ai. Indexes pypi releases for AI-agent ecosystem packages._
