Pytest
mathiasertl/django-ca
Instructions for running, writing, and maintaining tests in this project
Generates Pydantic v2 model classes from the JSON Schema documents under coffeeAGNTCY/coffeeagents/lungo/schema/jsonschemas/ into coffeeAGNTCY/coffeeagents/lungo/schema/types/.py, and a matching…
$ npx skills add agntcy/coffeeAgntcy --skill jsonschema-to-pydantic-lungo -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install agntcy/coffeeAgntcy jsonschema-to-pydantic-lungo --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/agntcy/coffeeAgntcy.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo .claude/skills/jsonschema-to-pydantic-lungo && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "jsonschema-to-pydantic-lungo" agent skill from https://github.com/agntcy/coffeeAgntcy/tree/main/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo into .claude/skills/jsonschema-to-pydantic-lungo/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jsonschema-to-pydantic-lungo", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/agntcy/coffeeAgntcy/tree/main/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungoType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add agntcy/coffeeAgntcy --skill jsonschema-to-pydantic-lungo -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install agntcy/coffeeAgntcy jsonschema-to-pydantic-lungo --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/agntcy/coffeeAgntcy.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo .agents/skills/jsonschema-to-pydantic-lungo && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "jsonschema-to-pydantic-lungo" agent skill from https://github.com/agntcy/coffeeAgntcy/tree/main/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo into .agents/skills/jsonschema-to-pydantic-lungo/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jsonschema-to-pydantic-lungo", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add agntcy/coffeeAgntcy --skill jsonschema-to-pydantic-lungo -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install agntcy/coffeeAgntcy jsonschema-to-pydantic-lungo --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/agntcy/coffeeAgntcy.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo .cursor/skills/jsonschema-to-pydantic-lungo && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "jsonschema-to-pydantic-lungo" agent skill from https://github.com/agntcy/coffeeAgntcy/tree/main/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo into .cursor/skills/jsonschema-to-pydantic-lungo/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jsonschema-to-pydantic-lungo", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/agntcy/coffeeAgntcy.git --path .agents/skills/domain-lungo/jsonschema-to-pydantic-lungo--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add agntcy/coffeeAgntcy --skill jsonschema-to-pydantic-lungo -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install agntcy/coffeeAgntcy jsonschema-to-pydantic-lungo --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/agntcy/coffeeAgntcy.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo .gemini/skills/jsonschema-to-pydantic-lungo && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "jsonschema-to-pydantic-lungo" agent skill from https://github.com/agntcy/coffeeAgntcy/tree/main/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo into .gemini/skills/jsonschema-to-pydantic-lungo/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jsonschema-to-pydantic-lungo", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install agntcy/coffeeAgntcy jsonschema-to-pydantic-lungoInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add agntcy/coffeeAgntcy --skill jsonschema-to-pydantic-lungo -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/agntcy/coffeeAgntcy.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo .github/skills/jsonschema-to-pydantic-lungo && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "jsonschema-to-pydantic-lungo" agent skill from https://github.com/agntcy/coffeeAgntcy/tree/main/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo into .github/skills/jsonschema-to-pydantic-lungo/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jsonschema-to-pydantic-lungo", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add agntcy/coffeeAgntcy --skill jsonschema-to-pydantic-lungo -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install agntcy/coffeeAgntcy jsonschema-to-pydantic-lungo --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/agntcy/coffeeAgntcy.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo .opencode/skills/jsonschema-to-pydantic-lungo && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "jsonschema-to-pydantic-lungo" agent skill from https://github.com/agntcy/coffeeAgntcy/tree/main/.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo into .opencode/skills/jsonschema-to-pydantic-lungo/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jsonschema-to-pydantic-lungo", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
jsonschema-to-pydantic-lungoGenerates Pydantic v2 model classes from the JSON Schema documents under coffeeAGNTCY/coffeeagents/lungo/schema/jsonschemas/ into coffeeAGNTCY/coffeeagents/lungo/schema/types/.py, and a matching…
Jsonschema To Pydantic Lungo is an agent skill from agntcy/coffeeAgntcy. Generates Pydantic v2 model classes from the JSON Schema documents under coffeeAGNTCY/coffeeagents/lungo/schema/jsonschemas/ into coffeeAGNTCY/coffeeagents/lungo/schema/types/.py, and a matching pytest module per types module under coffeeAGNTCY/coffeeagents/lungo/tests/unit/schemas/types/test<module.py. DO NOT TRIGGER AUTOMATICALLY. ASK THE USER IF THE SKILL SHOULD BE USED. Use when a v.json schema under that folder is added or modified, when regenerating the lungo Pydantic types or their tests after a schema…
Its SKILL.md is about 5.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 1 other file (for example `mapping-rules.md`).
It sits in Testing & QA, covering Unit testing. It works with Pydantic and pytest. The repository describes itself as: End-to-end reference application for AGNTCY Components. The licence is Apache-2.0.
3 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 78f588c. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
uvFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
github.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Jsonschema To Pydantic Lungo loads about 5.8k tokens when it runs. Until then it costs about 172 tokens; SKILL.md has 2,569 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from agntcy/coffeeAgntcy at commit 78f588c, republished under its Apache-2.0 licence (© agntcy). 2,569 words, ~5,810 tokens.
.claude/skills/jsonschema-to-pydantic-lungo/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.Generates one Pydantic v2 module per JSON Schema in coffeeAGNTCY/coffee_agents/lungo/schema/jsonschemas/*.json and one matching pytest module per generated types module. Output:
coffeeAGNTCY/coffee_agents/lungo/schema/types/<schema_name>.py (no _v<N> suffix).coffeeAGNTCY/coffee_agents/lungo/tests/unit/schemas/types/test_<schema_name>.py (same stem as the types module, prefixed with test_, parallel to the schema/types/ layout).__init__.py under schema/types/ is updated to re-export the public symbols.The generator is the schema. Do not read existing files in schema/types/ or tests/unit/schemas/types/test_<module>.py to decide naming, layout, or behaviour - they may be missing, stale, or wrong. The only authoritative inputs are:
.json files under schema/jsonschemas/ (excluding examples/).schema/jsonschemas/examples/ - used as round-trip baselines and as the source data that test mutations clone before invalidating.coffeeAGNTCY/coffee_agents/lungo/schema/json_schema.py (and any sibling modules under schema/).Copy this checklist and tick items as you go:
- [ ] 1. Enumerate input schemas under schema/jsonschemas/*.json (skip examples/)
- [ ] 2. Read each schema fully, including $defs, $ref, allOf, anyOf, propertyNames
- [ ] 3. Read schema/json_schema.py for Python-only constraints (e.g. validate_version_specific_criteria)
- [ ] 4. Generate one schema/types/<name>.py per schema, applying the mapping rules
- [ ] 5. Update schema/types/__init__.py: re-export every public class, type alias, and `*_from_uuid` helper
- [ ] 6. Generate one tests/unit/schemas/types/test_<name>.py per types module, applying the test-generation rules
- [ ] 7. Look for possibly affected non-generated consumer code and update it
- [ ] 8. Run: cd coffeeAGNTCY/coffee_agents/lungo && uv run --frozen pytest tests/unit/schemas/ -x
- [ ] 9. Run: cd coffeeAGNTCY/coffee_agents/lungo && uv run --frozen pytest tests/unit/ -xIf step 8 or 9 fails, identify which mapping rule(s) or test-generation rule(s) you applied incorrectly and re-emit the affected file(s) end-to-end - do not patch the failing portion in isolation.
If a rule itself seems wrong or insufficient to make the tests pass, surface that to the user instead of working around it.
| Source artefact | Target Python identifier |
|---|---|
event_v1.json | schema/types/event.py and tests/unit/schemas/types/test_event.py (strip the _v<N> version suffix) |
$defs.foo_bar | class FooBar (snake_case → PascalCase, no semantic renames) |
Top-level object schema with title: "Event (v1)" | class Event (title without parenthesised version) |
Top-level schema with no root type (enum-only / $defs-only file, e.g. event_type_v1.json) | no root class - the module just contains the $defs outputs |
$defs.<x>_id referencing <prefix>://<UUID> strings | class <X>Id(RootModel[str]) + helper <x>_id_from_uuid |
Cross-schema $ref (e.g. event_type_v1.json#/$defs/event_type) | from schema.types.<other_module> import <Class> |
| Enum member name | SCREAMING_SNAKE_CASE of the value, even when the value itself is PascalCase. Example: RECRUITER_NODE_SEARCH = "RecruiterNodeSearch". |
The class name is derived mechanically from the $defs key. Do not shorten, expand, or reinterpret the name. You should, however, translate it from snake_case to PascalCase. For example, stable_agent_id becomes StableAgentId, never AgentId. If a consumer breaks because of a rename, that's the consumer's bug to fix, not the skill's.
$defs)Whenever an anyOf branch is an allOf that references two or more $defs, that branch produces a merged leaf class with no $def name of its own. The rule applies regardless of where the branch sits in the anyOf (schemas are human-written; ordering is not a contract) and regardless of how many $defs are composed.
For each unique composition, pick a name that:
$def keys.PartialNodeWithAgentExtension over PartialNodeWithPartialNodeAgentExtension).$defs as the base and the rest as extensions. The base is most easily identified as the $def that another branch in the same anyOf references alone (or with fewer extensions). Falling back: pick the $def with the largest field set, or the one whose name does not look extension-shaped (e.g. lacks an _extension / _ext suffix).<Base>With<Ext1>And<Ext2>.... If the chain becomes unreadable, pick a domain-meaningful umbrella token instead - record the choice in the class docstring.The merged class name must be a function of the set of composed $defs, not of the branch position. Two branches that compose the same set must resolve to the same class.
A $def that is only ever referenced inside an allOf composing a merged class is not emitted as a standalone class: its fields appear directly on the merged class instead. If the same $def is also referenced standalone elsewhere in the schema, emit it standalone too.
This rule applies whenever the composition is anonymous. If the schema gives the composition its own $def name (as partial_agent_node / agent_node do in event_v1.json), follow the standard naming rule and emit classes named after that key - see mapping-rules.md §D for how the named-composition case interacts with sibling-key discrimination.
Every generated file starts with:
# Copyright AGNTCY Contributors (https://github.com/agntcy)
# SPDX-License-Identifier: Apache-2.0
"""Generated from ``schema/jsonschemas/<source_file>.json``.
Do not edit by hand: regenerate with the ``jsonschema-to-pydantic-lungo`` skill.
<short paraphrase of the schema's `title` and `description`>
"""Use from __future__ import annotations and group imports stdlib → third-party → first-party (schema.*).
| Schema construct | Pydantic v2 emission |
|---|---|
type: string, pattern: P | Annotated[str, Field(pattern=P)] |
type: string, minLength: 1 | Annotated[str, Field(min_length=1)] |
type: string, format: date-time | pydantic.AwareDatetime |
type: string, enum: [...] | class X(StrEnum): ... (preserve string values verbatim) |
type: number, default: V | float = V |
type: boolean, default: V | bool = V |
type: object, additionalProperties: false | model_config = ConfigDict(extra="forbid") |
type: object, additionalProperties: true (or unspecified for an extensible object) | model_config = ConfigDict(extra="allow") |
| Required field | bare type, no default |
| Optional field, no default | <Type> | None = None |
Optional field with default: V | <Type> = V (no | None) |
$ref: "#/$defs/foo" | use the generated Foo class as the field type |
$ref: "<other>_v<N>.json#/$defs/foo" | import Foo from schema.types.<other> |
Top-level schema additionalProperties: false | Event (or equivalent root) gets extra="forbid" |
Anything that constrains a single value in isolation - pattern, minLength, maximum, format, enum, propertyNames on a dict - must be expressed in the field's Annotated[...] type. Validators (@field_validator, @model_validator) are only for cross-field constraints.
For propertyNames: { $ref: "#/$defs/<id_def>" } on a dict-shaped property, embed the constraint into the dict key annotation.
For example:
instances: dict[
Annotated[str, Field(pattern=_INSTANCE_ID_REGEX)], WorkflowInstance
]See mapping-rules.md §A for the full example.
<prefix>://<UUID> strings always pair RootModel with a <def>_from_uuid helperFor every $defs.<x>_id whose pattern matches ^<prefix>://<UUID>$:
class <X>Id(RootModel[str]) with the pattern= constraint.def <x>_id_from_uuid(<x>_uuid: UUID) -> <X>Id: immediately below the class. Use f"<prefix>://{<x>_uuid!s}" to build the string.Helper name is always <schema_def_name>_from_uuid, even if the prefix differs from the def name (e.g. stable_agent_id → prefix agent:// → helper stable_agent_id_from_uuid).
allOf [partial, {required: [...]}] → standalone full class, not a subclassWhen a $def is allOf [partial_<X>, { required: [<all_fields>] }], generate two unrelated classes (Partial<X> and <X>) with their fields re-declared. Do not subclass: Optional/| None types from the partial would leak into the full form.
class PartialThing(BaseModel):
model_config = ConfigDict(extra="allow")
a: SomeType | None = None
b: SomeType | None = None
class Thing(BaseModel): # NOT (PartialThing) - fields are required here
model_config = ConfigDict(extra="allow")
a: SomeType
b: SomeTypeanyOf discriminated by sibling-key presence → Discriminator callableWhen the anyOf branches differ by which keys are present (typically one branch has not { anyOf: [{ required: [k1] }, { required: [k2] }, ...] } and another allOfs in a sibling extension $def that requires those keys), encode the choice with a callable pydantic.Discriminator whose only job is to mirror that sibling-key presence test. Leave any full vs. partial sub-choice to Pydantic's smart union inside each branch.
Type-first exception (event_v1 1.2.1, Pydantic only): the JSON Schema anyOf stays presence-only so leftover type=agent/mcp without extension keys remain schema-valid. This repo's discriminator consults type before the presence test. Import the frozensets from schema.node_types (AGENT_EXTENSION_TYPES, BASE_NODE_TYPES); do not duplicate the string literals. Emitters re-export the same names from common.workflow_utils.node_types. Routing:
type in {agent, mcp} → tag agent (even if extension keys are absent; the branch constraints then fail).type in {transport, transportNode, group, directory} → tag base.customNode, omitted type, unknown) → existing presence test (agent_record_uri / stable_agent_id).AgentNode / PartialAgentNode → agent; BaseNode / PartialBaseNode → base).The discriminator still only routes. No field-count checks, no __pydantic_extra__ police.
def _kind_discriminator(value: Any) -> str | None:
if isinstance(value, (FullExt, PartialExt)):
return "with_extension"
if isinstance(value, (FullPlain, PartialPlain)):
return "plain"
if not isinstance(value, dict):
return None
if "ext_required_key" in value or "ext_optional_key" in value:
return "with_extension"
return "plain"
ItemUnion = Annotated[
Union[
Annotated[Union[FullPlain, PartialPlain], Tag("plain")],
Annotated[Union[FullExt, PartialExt], Tag("with_extension")],
],
Discriminator(_kind_discriminator),
]Why this shape:
anyOf decision. Never put field-count or per-field validity checks in it.Union[Full, Partial]. Smart union picks Full when all the extra required fields are populated, else Partial.Field / pattern constraints (e.g. String should match pattern '^agent://...') instead of a custom "extra fields not allowed" message.@model_validator(mode="after") that polices __pydantic_extra__ for sibling-extension keys leaking into a non-extension variant. The discriminator already routes them to the right branch.See mapping-rules.md §D for the full worked example covering schemas with not { required } clauses.
schema/json_schema.pyJSON Schema can't express "dict key X must equal nested value's id field" or similar relationships. Look in coffeeAGNTCY/coffee_agents/lungo/schema/json_schema.py for functions called from validate_version_specific_criteria (and any equivalent module). Each schema-name-gated check there must be re-implemented as a Pydantic @model_validator(mode="after").
Where to attach the validator: place it on the smallest class that owns every field the check reads. Do not push it up to the root just because the source helper happens to start its traversal at the root.
Example: _enforce_workflow_instance_map_key_id_match reads workflow.instances keys and workflow_instance.id. Both live inside the Workflow class (the dict is its instances field; each value is a WorkflowInstance whose id it can dereference). So the validator goes on Workflow, not on Event or Data.
The validator's docstring must point back at the source helper, e.g.:
mirrors ``schema.json_schema._enforce_workflow_instance_map_key_id_match``__init__.py regenerationschema/types/__init__.py re-exports every public symbol from each generated module. Keep three groups, each alphabetised:
schema.types.<module>.__all__ tuple/list in the same order as the imports.Public symbols include: every class declared at module level, every type alias (e.g. TopologyNodeItem, Node, PartialNode), and every <name>_from_uuid helper.
For every generated schema/types/<name>.py emit a matching pytest module at tests/unit/schemas/types/test_<name>.py (the tests/unit/schemas/types/ directory mirrors schema/types/). Very short and not meaningful types files don't need to have tests generated for them unless instructed by the user.
These test files are owned by this skill: do not read the existing ones to decide layout; re-emit. However, if a file under schema/types/<name>.py has not changed, then don't generate a new test file for it, unless specifically instructed by the user.
The goal of every test in these modules is to verify that the generated Pydantic types agree with both (a) the JSON Schema layer (schema.validation.validate_data_against_schema) and (b) the Python validation logic in coffeeAGNTCY/coffee_agents/lungo/schema/json_schema.py (and any sibling modules) that doesn't fit into JSON Schema - Pydantic Discriminator callables, @model_validator cross-field checks, and @field_validator whole-value checks should usually all live alongside the schema-driven cases in the same tables, if possible, not in separate "discriminator-only" or "validator-only" tables.
Same license header and Generated from ... docstring shape as the types module, pointing at the source .json. Use from __future__ import annotations and group imports stdlib → third-party → first-party (schema.*).
Don't re-explain the rules from this SKILL used to generate the file.
For every test function in the file:
Case = NamedTuple with case_id: str and one or two sub-NamedTuples (Inputs, optional Outputs). The top-level tuple is always the Case shape; only add Outputs when the expected result needs more than one field (e.g. distinguishing "valid" from "raises type X"). For tests where the expected result is fully derivable from the inputs (e.g. an id helper that always builds f"{prefix}://{uuid}"), Outputs may be omitted and the assertion derived from inputs directly._<UPPERCASE>_CASES: tuple[<Case>, ...] = (...) table. Multiple tables per file is the norm - one per concern (id helpers, id pattern enforcement, top-level model agreement, enum member values, parent-schema acceptance, etc.). Do not collapse heterogeneous concerns into a single table.@pytest.mark.parametrize("case", [pytest.param(c, id=c.case_id) for c in _<UPPERCASE>_CASES]) so the case id is the pytest test id._mutate_<case_id> and declare them in a single block right above the table that references them. The test body deepcopies the example before invoking the mutation. (For round-trip cases, inputs.mutate is None; assert that in the test body so a future case can't accidentally combine "valid" with a mutation.)The set of tables in a generated test module is a function of what the corresponding types module emits. Use the following recipe:
class <X>Id(RootModel[str]) plus <x>_id_from_uuid helper: there's no need to generate dedicated tests for these. They should be covered by cases in other types that use them.class <X>(StrEnum): there's no need to generated dedicated tests for these. They should be covered by cases in other types that use them.Event etc.): one _<MODEL>_CASES table whose rows are either round-trip rows (every packaged example file under schema/jsonschemas/examples/, with no mutation) or invalidation rows (same example, with a mutation that violates a single named invariant). Cases must collectively cover, at minimum:additionalProperties: false boundary the schema declares,pattern constraint reachable from the root (e.g. malformed metadata.id, malformed metadata.correlation.id),enum constraint reachable from the root (assigning an unknown member),required: [...] field (deletion of the required key - this exercises both the JSON Schema required clause and Pydantic's "field required" error),schema/json_schema.py that the validator-rule rule (Rule E) implements as a Pydantic @model_validator (e.g. instances map key vs. nested id),Discriminator decision in the types module (input data that should route to each branch must already be exercised by the round-trip examples; if a packaged example doesn't cover both branches of a discriminator, add a focused round-trip row that does, using a deepcopy of an existing example mutated to flip the routing).Round-trip body: validate via validate_data_against_schema(data, "<schema_name>"), then <Model>.model_validate(data), then dumped = model.model_dump(mode="json", exclude_none=True), then re-validate dumped through both layers. Also assert isinstance(dumped[...], str) for any format: date-time fields and that the corresponding model.<...>.tzinfo is not None.
Invalid body: assert that both validate_data_against_schema and <Model>.model_validate raise - typically SchemaValidationError and pydantic.ValidationError respectively. The Outputs sub-NamedTuple usually pins both exception types: EventOutputs(schema_exc, model_exc). An invalid case where only one layer rejects the input is a bug in either the types module (Pydantic too lax/strict) or the schema (the JSON Schema doesn't encode the constraint and there's no Python @model_validator for it) - surface it to the user instead of writing a one-sided test.
pytest.raises against each in sequence).schema/jsonschemas/examples/ and mutate copies for invalidation rows.After generating, both must pass:
cd coffeeAGNTCY/coffee_agents/lungo
uv run --frozen pytest tests/unit/schemas/ # schema-layer tests + generated tests/unit/schemas/types/test_<module>.py
uv run --frozen pytest tests/unit/ # consumer compatibilityIf a consumer fails because of a rename you introduced (e.g. it imported the old class name), report the failure to the user and ask before touching non-generated code.
schema/types/<name>.py to decide naming.tests/unit/schemas/types/test_<name>.py to decide layout - generated tests are re-emitted end-to-end from the schema and the corresponding types module.Partial<X> from <X> (or vice versa) when allOf only adds required fields.@model_validator(mode="after") to police __pydantic_extra__ for fields that should belong to a sibling union variant.Discriminator callable. The discriminator answers exactly one question: which schema anyOf branch.@field_validator for a constraint that fits in Annotated[..., Field(...)].AgentId for stable_agent_id, Node for base_node). Names come straight from $defs keys.mapping-rules.md - full worked examples for the trickier rules (A, C, D), including the schema fragment and the corresponding emitted Pydantic code.© agntcy, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 1 other file in .agents/skills/domain-lungo/jsonschema-to-pydantic-lungo of agntcy/coffeeAgntcy.
Open the folder on GitHubat commit 78f588c
Jsonschema To Pydantic Lungo next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Jsonschema To Pydantic Lungo this skillagntcy/coffeeAgntcy | 112 | — | ~5.8k | Automated safety check: Pass | Apache-2.0 | |
| Pytestmathiasertl/django-ca | 158 | — | ~924 | Automated safety check: Pass | GPL-3.0 | |
| PythonMadAppGang/claude-code | 285 | — | ~2.8k | Automated safety check: Notes | MIT | |
| Mastering Python SkillSpillwaveSolutions/agent-brain | 119 | — | ~1.4k | Automated safety check: Notes | MIT | |
| Fastapi Patternsaffaan-m/ECC | 277k | 1 repos | ~3.9k | Automated safety check: Notes | MIT | |
| Fastapi Endpointdavila7/claude-code-templates | 33k | — | ~3.9k | Automated safety check: Pass | MIT |
mathiasertl/django-ca
Instructions for running, writing, and maintaining tests in this project
MadAppGang/claude-code
A skill your agent uses when building FastAPI applications, implementing async endpoints, setting up Pydantic schemas, working with SQLAlchemy, or writing pytest tests for Python backend services.
SpillwaveSolutions/agent-brain
Modern Python coaching covering language foundations through advanced production patterns.
affaan-m/ECC
FastAPI best practices covering project structure, Pydantic v2 schemas, dependency injection, async handlers, authentication, authorization, transactional service layers, and testing with httpx and…
davila7/claude-code-templates
Plan and build production-ready FastAPI endpoints with async SQLAlchemy, Pydantic v2 models, dependency injection for auth, and pytest tests.
google/adk-python
Checks that every Python code block in a Markdown file actually compiles and runs, by extracting each block to a temporary file, executing it in an isolated subprocess, and writing a pass/fail…
agntcy/coffeeAgntcy
A skill your agent uses when the user asks about A2A (Agent-to-Agent) protocol communication, OASF record formats, AGNTCY directory operations, agent card parsing, or dirctl CLI usage.
agntcy/coffeeAgntcy
Guides adding a new repository operation (a check, validation, or piece of tooling) through this repo's standard script - Taskfile task - skill - CI enforcement - rule pipeline.
agntcy/coffeeAgntcy
Authors and maintains the human-facing Agentic Workflows API documentation for the lungo subproject at coffeeAGNTCY/coffeeagents/lungo/docs/workflow-instanceapi.md.
agntcy/coffeeAgntcy
Checks whether any Helm chart under coffeeAGNTCY/coffeeagents/{corto,lungo}/deployment/helm// has content changes not covered by a later Chart.yaml version: bump, anywhere in that chart's history…
agntcy/coffeeAgntcy
Runs task pins:check to find any third-party GitHub Action, reusable-workflow, or image reference that isn't pinned to an immutable SHA/digest, and pins each one it finds.
agntcy/coffeeAgntcy
Runs task workflows:check-permissions to find any GitHub Actions workflow file with a write-all grant or no declared permissions, and scopes it down to least privilege.
Categories
Generates Pydantic v2 model classes from the JSON Schema documents under coffeeAGNTCY/coffeeagents/lungo/schema/jsonschemas/ into coffeeAGNTCY/coffeeagents/lungo/schema/types/.py, and a matching…. Jsonschema To Pydantic Lungo is an agent skill from agntcy/coffeeAgntcy.py.
Jsonschema To Pydantic Lungo fits situations like: A v.json schema under that folder is added; regenerating the lungo Pydantic types; their tests after a schema change; the user mentions regenerating schema types.
Run `npx skills add agntcy/coffeeAgntcy --skill jsonschema-to-pydantic-lungo -a claude-code`. Or copy the skill folder (.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo in agntcy/coffeeAgntcy) into .claude/skills/jsonschema-to-pydantic-lungo in your project. Claude Code loads it when a task matches its description.
Run `npx skills add agntcy/coffeeAgntcy --skill jsonschema-to-pydantic-lungo -a codex`. Or copy the skill folder (.agents/skills/domain-lungo/jsonschema-to-pydantic-lungo in agntcy/coffeeAgntcy) into .agents/skills/jsonschema-to-pydantic-lungo in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add agntcy/coffeeAgntcy --skill jsonschema-to-pydantic-lungo -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/jsonschema-to-pydantic-lungo, .gemini/skills/jsonschema-to-pydantic-lungo, .github/skills/jsonschema-to-pydantic-lungo and .opencode/skills/jsonschema-to-pydantic-lungo in your project.
Going by SKILL.md and its folder, Jsonschema To Pydantic Lungo needs the command-line tools its instructions call (uv). Our summary lists: Python 3.
SKILL.md names 1 domain. In commands or code: github.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Jsonschema To Pydantic Lungo is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.8k tokens (SKILL.md is roughly 23k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Jsonschema To Pydantic Lungo: Pytest (mathiasertl/django-ca, 158 stars), Python (MadAppGang/claude-code, 285 stars), Mastering Python Skill (SpillwaveSolutions/agent-brain, 119 stars) and Fastapi Patterns (affaan-m/ECC, 277k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
agntcy (a GitHub organization) maintains it in agntcy/coffeeAgntcy, which has 112 GitHub stars. The repository holds 20 skills in this directory. The repository was last updated on October 9, 2026.
Source: agntcy/coffeeAgntcy on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.