agentsclimarketplace

Strict pydantic config with suggestions

Skill kjuhwa/skills-hub/skills/configuration/strict-pydantic-config-with-suggestions

Forbid unknown fields on every config model and reject misspellings with a "did you mean ..." suggestion drawn from difflib.get_close_matches, while stripping whitespace from all string values automatically.From its SKILL.md

Install
npx -y skills add kjuhwa/skills-hub --skill strict-pydantic-config-with-suggestions

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

3.2 KB, 576 tokens by cl100k_base, as published. Nobody here has run it

Strict Pydantic Config Base with "Did You Mean" Suggestions

When to use

You want every YAML/JSON config in your project to fail loudly on typos like endpiont instead of endpoint, and surface the suggestion inline so users don't have to grep docs. Inherit a single base class and you get whitespace stripping for free.

How it works

  • model_config = ConfigDict(extra="forbid") rejects unknown fields.
  • A model_validator(mode="before") intercepts the raw dict, computes the unknown keys, and uses difflib.get_close_matches to attach a suggestion per offender. It raises a single ValueError with all suggestions inline — much friendlier than Pydantic's default unknown-field error.
  • A field_validator("*", mode="before") strips whitespace from any string value globally.
  • Field aliases are honored when computing the allowed-set so YAML keys match without surprises.

Example

from difflib import get_close_matches
from pydantic import BaseModel, ConfigDict, field_validator, model_validator

class StrictConfigModel(BaseModel):
    model_config = ConfigDict(extra="forbid")

    @field_validator("*", mode="before")
    @classmethod
    def _strip_string_values(cls, value):
        return value.strip() if isinstance(value, str) else value

    @model_validator(mode="before")
    @classmethod
    def _reject_unknown_fields(cls, data):
        if not isinstance(data, dict):
            return data
        allowed = set(cls.model_fields) | {
            f.alias for f in cls.model_fields.values()
            if f.alias and f.alias != cls._name(f)
        }
        extras = sorted(k for k in data if k not in allowed)
        if not extras:
            return data
        details = []
        for name in extras:
            suggestion = get_close_matches(name, list(allowed), n=1)
            if suggestion:
                details.append(f"'{name}' (did you mean '{suggestion[0]}'?)")
            else:
                details.append(f"'{name}'")
        raise ValueError(
            f"Unexpected field {details[0]}." if len(details) == 1
            else f"Unexpected fields {', '.join(details)}."
        )

Gotchas

  • Whitespace stripping affects every string field; if you have a field that legitimately needs leading whitespace, override the validator on that subclass.
  • extra="forbid" cascades — every subclass gets it; opt out per-subclass if you genuinely need extras.
  • The "before" model validator runs on the raw input dict, so it sees alias keys and field names side-by-side; build the allowed set from both.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,871. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.