Files
jambo/README.md

282 lines
6.4 KiB
Markdown

# Jambo - JSON Schema to Pydantic Converter
<p style="text-align:center">
<a href="https://github.com/HideyoshiNakazone/jambo" target="_blank">
<img src="https://img.shields.io/github/last-commit/HideyoshiNakazone/jambo.svg" alt="Last commit">
<img src="https://github.com/HideyoshiNakazone/jambo/actions/workflows/build.yml/badge.svg" alt="Tests">
</a>
<a href="https://codecov.io/gh/HideyoshiNakazone/jambo" target="_blank">
<img src="https://codecov.io/gh/HideyoshiNakazone/jambo/branch/main/graph/badge.svg" alt="Coverage">
</a>
<br />
<a href="https://pypi.org/project/jambo" target="_blank">
<img src="https://badge.fury.io/py/jambo.svg" alt="Package version">
</a>
<a href="https://github.com/HideyoshiNakazone/jambo" target="_blank">
<img src="https://img.shields.io/pypi/pyversions/jambo.svg" alt="Python versions">
<img src="https://img.shields.io/github/license/HideyoshiNakazone/jambo.svg" alt="License">
</a>
</p>
**Jambo** is a Python package that automatically converts [JSON Schema](https://json-schema.org/) definitions into [Pydantic](https://docs.pydantic.dev/) models.
It's designed to streamline schema validation and enforce type safety using Pydantic's validation features.
Created to simplify the process of dynamically generating Pydantic models for AI frameworks like [LangChain](https://www.langchain.com/), [CrewAI](https://www.crewai.com/), and others.
---
## ✨ Features
- ✅ Convert JSON Schema into Pydantic models dynamically;
- 🔒 Supports validation for:
- strings
- integers
- floats
- booleans
- arrays
- nested objects
- allOf
- anyOf
- oneOf
- ref
- enum
- const
- ⚙️ Enforces constraints like `minLength`, `maxLength`, `pattern`, `minimum`, `maximum`, `uniqueItems`, and more;
- 📦 Zero config — just pass your schema and get a model.
---
## 📦 Installation
```bash
pip install jambo
```
---
## 🚀 Usage
There are two ways to build models with Jambo:
1. The original static API: `SchemaConverter.build(schema)` doesn't persist any reference cache between calls and doesn't require any configuration.
2. The new instance API: use a `SchemaConverter()` instance and call `build_with_cache`, which exposes and persists a reference cache and helper methods.
The instance API is useful when you want to reuse generated subtypes, inspect cached models, or share caches between converters; all leveraging namespaces via the `$id` property in JSON Schema. See the docs for full details: https://jambo.readthedocs.io/en/latest/usage.ref_cache.html
### Static (compatibility) example
```python
from jambo import SchemaConverter
schema = {
"title": "Person",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
},
"required": ["name"],
}
# Old-style convenience API (kept for compatibility)
Person = SchemaConverter.build(schema)
obj = Person(name="Alice", age=30)
print(obj)
```
### Instance API (recommended for cache control)
```python
from jambo import SchemaConverter
converter = SchemaConverter()
schema = {
"title": "Person",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"address": {"type": "object", "properties": {"street": {"type": "string"}}},
},
"required": ["name"],
}
# build_with_cache populates the converter's instance-level ref cache
Person = converter.build_with_cache(schema)
# you can retrieve cached subtypes by name/path
cached_person = converter.get_cached_ref("Person")
# clear the instance cache when needed
converter.clear_ref_cache()
```
---
## ✅ Example Validations
Following are some examples of how to use Jambo to create Pydantic models with various JSON Schema features, but for more information, please refer to the [documentation](https://jambo.readthedocs.io/).
### Strings with constraints
```python
from jambo import SchemaConverter
schema = {
"title": "EmailExample",
"type": "object",
"properties": {
"email": {
"type": "string",
"minLength": 5,
"maxLength": 50,
"pattern": r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
},
},
"required": ["email"],
}
Model = SchemaConverter.build(schema)
obj = Model(email="user@example.com")
print(obj)
```
### Integers with bounds
```python
from jambo import SchemaConverter
schema = {
"title": "AgeExample",
"type": "object",
"properties": {
"age": {"type": "integer", "minimum": 0, "maximum": 120}
},
"required": ["age"],
}
Model = SchemaConverter.build(schema)
obj = Model(age=25)
print(obj)
```
### Nested Objects
```python
from jambo import SchemaConverter
schema = {
"title": "NestedObjectExample",
"type": "object",
"properties": {
"address": {
"type": "object",
"properties": {
"street": {"type": "string"},
"city": {"type": "string"},
},
"required": ["street", "city"],
}
},
"required": ["address"],
}
Model = SchemaConverter.build(schema)
obj = Model(address={"street": "Main St", "city": "Gotham"})
print(obj)
```
### References
```python
from jambo import SchemaConverter
schema = {
"title": "person",
"$ref": "#/$defs/person",
"$defs": {
"person": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"emergency_contact": {
"$ref": "#/$defs/person",
},
},
}
},
}
model = SchemaConverter.build(schema)
obj = model(
name="John",
age=30,
emergency_contact=model(
name="Jane",
age=28,
),
)
```
---
## 🧪 Running Tests
To run the test suite:
```bash
poe tests
```
Or manually:
```bash
python -m unittest discover -s tests -v
```
---
## 🛠 Development Setup
To set up the project locally:
1. Clone the repository
2. Install [uv](https://github.com/astral-sh/uv) (if not already installed)
3. Install dependencies:
```bash
uv sync
```
4. Set up git hooks:
```bash
poe create-hooks
```
---
## 📌 Roadmap / TODO
- [ ] Better error reporting for unsupported schema types
---
## 🤝 Contributing
PRs are welcome! This project uses MIT for licensing, so feel free to fork and modify as you see fit.
---
## 🧾 License
MIT License.