# scheLLMa
_Schemas for LLMs and Structured Output_
[](https://andrader.github.io/schellma/)
[](https://andrader.github.io/schellma/demo/)
[](https://www.python.org/downloads/)
[](https://badge.fury.io/py/schellma)

Converts Pydantic models/JSON Schemas to clean, simplified type definitions perfect for **generating structured output** with **LLM prompts**. 
Unlike verbose JSON Schema formats, **scheLLMa** produces readable, concise type definitions that are ideal for language model interactions and structured output generation:
- **Reduce token usage** - Concise format saves on API costs
- **Minimize parsing errors** - Simple syntax is easier for models to parse, less verbose than JSON Schema, reducing confusion
- **Stay readable** - Human-friendly format for prompt engineering
View the [documentation](https://andrader.github.io/schellma/) for more details.
Checkout the [demo](https://andrader.github.io/schellma/demo/) for more examples!
Combine it with parsing libs, like `openai` sdk or `Instructor` for AWESOME results!
- [scheLLMa](#schellma)
  - [Features](#features)
  - [Quick Start](#quick-start)
    - [Using the new openai chat.completions.**parse** API](#using-the-new-openai-chatcompletionsparse-api)
    - [Using the new openai Responses API](#using-the-new-openai-responses-api)
  - [Installation](#installation)
    - [Comparison with JSON Schema](#comparison-with-json-schema)
  - [Advanced Usage with Type Definitions](#advanced-usage-with-type-definitions)
  - [Examples](#examples)
    - [Enum Support](#enum-support)
    - [Complex Nested Structures](#complex-nested-structures)
  - [Development](#development)
    - [Setup](#setup)
    - [Running Tests](#running-tests)
    - [Type Checking](#type-checking)
    - [Linting](#linting)
  - [Contributing](#contributing)
    - [Development Guidelines](#development-guidelines)
  - [License](#license)
  - [Changelog](#changelog)
## Features
- 🤖 **Optimized for LLM prompts** - Clean, readable type definitions
- 💰 **Token-efficient** - Reduces LLM API costs
- 🎯 **Support for all common Python types** (str, int, bool, datetime, etc.)
- 🏗️ **Handle complex nested structures and collections** - Strong support for Pydantic model types
- 🔗 **Support for enums, optional types, and unions** - Properly extract and display union types
- ⚙️ **Customizable output formatting** - Indentation, compact mode, and more
- 🎨 **Rich Default Values** - Automatically shows default values in human-readable comments
- 📏 **Smart Constraints** - Displays field constraints (length, range, patterns) in clear language
- ✅ **Clear Field Status** - Explicit required/optional marking
- 📚 **Rich Examples** - Inline examples and documentation for better LLM understanding
- 🔀 **Advanced Union Types** - Full support for allOf, not constraints, and discriminated unions
- 🔢 **Advanced Arrays** - Contains constraints, minContains/maxContains, and enhanced tuple support
## Quick Start
View the [demo](demo.md) for more examples and features!
```python
from pydantic import BaseModel
from schellma import schellma
import openai
class TaskRequest(BaseModel):
    title: str
    priority: int
    tags: list[str]
    due_date: str | None = None
# Generate schema for LLM prompt
schema = schellma(TaskRequest)
# Add the scheLLMa schema to the prompt
prompt = f"""
Please create a task with the following structure:
{schema}
"""
print(prompt)
# Use with your favorite LLM API
completion = openai.chat.completions.create(
    model="gpt-4.1-mini",
    messages=[{
        "role": "user",
        "content": prompt
    }]
)
content = completion.choices[0].message.content
print(content)
task = TaskRequest.model_validate_json(clean_content(content))
print(task)
# TaskRequest(title='Task 1', priority=1, tags=['tag1', 'tag2'], due_date=None)
```
### Using the new openai chat.completions.**parse** API
```python
# or directly parse with openai sdk
completion = openai.chat.completions.parse(
    model="gpt-4.1-mini",
    messages=[{
        "role": "user",
        "content": prompt
    }]
)
task = completion.choices[0].message.parsed
print(task)
# TaskRequest(title='Task 1', priority=1, tags=['tag1', 'tag2'], due_date=None)
```
### Using the new openai Responses API
```python
class CalendarEvent(BaseModel):
    name: str
    date: str
    participants: list[str]
schema = schellma(CalendarEvent)
response = openai.responses.parse(
    model="gpt-4o-2024-08-06",
    input=[
        # Make sure to include the schema in your prompt
        {"role": "system", "content": f"Extract the event information. {schema}"},
        {
            "role": "user",
            "content": "Alice and Bob are going to a science fair on Friday.",
        },
    ],
    text_format=CalendarEvent,
)
event = response.output_parsed
print(event)
# CalendarEvent(name='Alice and Bob are going to a science fair on Friday.', date='Friday', participants=['Alice', 'Bob'])
```
## Installation
```bash
pip install schellma
```
Or using uv:
```bash
uv add schellma
```
Install from github
```bash
uv add git+https://github.com/andrader/schellma.git
```
### Comparison with JSON Schema
**JSON Schema (verbose, token-heavy):**
```json
{
  "type": "object",
  "properties": {
    "name": { "type": "string" },
    "age": { "type": "integer" },
    "email": { "type": ["string", "null"], "default": null }
  },
  "required": ["name", "age"],
  "additionalProperties": false
}
```
**scheLLMa (clean, token-efficient):**
```typescript
{
    "name": string,
    "age": int,
    "email": string | null,
}
```
## Advanced Usage with Type Definitions
```python
from pydantic import BaseModel
from typing import List, Optional
from schellma import schellma
class Address(BaseModel):
    street: str
    city: str
    country: str
class User(BaseModel):
    name: str
    age: int
    addresses: List[Address]
    primary_address: Optional[Address] = None
# Generate with separate type definitions
schema = schellma(User, define_types=True)
print(schema)
```
Output:
```typescript
Address {
    "street": string,
    "city": string,
    "country": string,
}
{
    "name": string,
    "age": int,
    "addresses": Address[],
    "primary_address": Address | null,
}
```
## Examples
View more exemples at [Demo](#demo.md)
### Enum Support
```python
from enum import Enum
from pydantic import BaseModel
class Status(Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
class Task(BaseModel):
    title: str
    status: Status
schema = schellma(Task)
# Output: { "title": string, "status": "active" | "inactive" }
```
### Complex Nested Structures
```python
from pydantic import BaseModel
from typing import Dict, List
class Tag(BaseModel):
    name: str
    color: str
class Post(BaseModel):
    title: str
    content: str
    tags: List[Tag]
    metadata: Dict[str, str]
schema = schellma(Post, define_types=True)
```
## Development
### Setup
```bash
git clone https://github.com/andrader/schellma.git
cd schellma
uv sync --dev
```
### Running Tests
```bash
uv run python -m pytest
```
### Type Checking
```bash
uv run mypy src/schellma/
```
### Linting
```bash
uv run ruff check src/schellma/
uv run ruff format src/schellma/
```
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
### Development Guidelines
1. Follow the existing code style (enforced by ruff)
2. Add tests for any new functionality
3. Update documentation as needed
4. Ensure all tests pass and type checking succeeds
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Changelog
See [Changelog](CHANGELOG.md) for the changelog.
            
         
        Raw data
        
            {
    "_id": null,
    "home_page": null,
    "name": "schellma",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": "Rubens <38709237+andrader@users.noreply.github.com>",
    "keywords": "ai, clean-schema, language-models, llm, prompts, pydantic, schema",
    "author": null,
    "author_email": "Rubens <38709237+andrader@users.noreply.github.com>",
    "download_url": "https://files.pythonhosted.org/packages/47/d4/43712bb2c2aa0cc23a1ac87dba0c644aec2b7c61690d1e2e283ff131c42c/schellma-0.4.0.tar.gz",
    "platform": null,
    "description": "# scheLLMa\n\n_Schemas for LLMs and Structured Output_\n\n[](https://andrader.github.io/schellma/)\n[](https://andrader.github.io/schellma/demo/)\n[](https://www.python.org/downloads/)\n[](https://badge.fury.io/py/schellma)\n\n\n\n\nConverts Pydantic models/JSON Schemas to clean, simplified type definitions perfect for **generating structured output** with **LLM prompts**. \n\nUnlike verbose JSON Schema formats, **scheLLMa** produces readable, concise type definitions that are ideal for language model interactions and structured output generation:\n\n- **Reduce token usage** - Concise format saves on API costs\n- **Minimize parsing errors** - Simple syntax is easier for models to parse, less verbose than JSON Schema, reducing confusion\n- **Stay readable** - Human-friendly format for prompt engineering\n\nView the [documentation](https://andrader.github.io/schellma/) for more details.\n\nCheckout the [demo](https://andrader.github.io/schellma/demo/) for more examples!\n\nCombine it with parsing libs, like `openai` sdk or `Instructor` for AWESOME results!\n\n- [scheLLMa](#schellma)\n  - [Features](#features)\n  - [Quick Start](#quick-start)\n    - [Using the new openai chat.completions.**parse** API](#using-the-new-openai-chatcompletionsparse-api)\n    - [Using the new openai Responses API](#using-the-new-openai-responses-api)\n  - [Installation](#installation)\n    - [Comparison with JSON Schema](#comparison-with-json-schema)\n  - [Advanced Usage with Type Definitions](#advanced-usage-with-type-definitions)\n  - [Examples](#examples)\n    - [Enum Support](#enum-support)\n    - [Complex Nested Structures](#complex-nested-structures)\n  - [Development](#development)\n    - [Setup](#setup)\n    - [Running Tests](#running-tests)\n    - [Type Checking](#type-checking)\n    - [Linting](#linting)\n  - [Contributing](#contributing)\n    - [Development Guidelines](#development-guidelines)\n  - [License](#license)\n  - [Changelog](#changelog)\n\n\n## Features\n\n- \ud83e\udd16 **Optimized for LLM prompts** - Clean, readable type definitions\n- \ud83d\udcb0 **Token-efficient** - Reduces LLM API costs\n- \ud83c\udfaf **Support for all common Python types** (str, int, bool, datetime, etc.)\n- \ud83c\udfd7\ufe0f **Handle complex nested structures and collections** - Strong support for Pydantic model types\n- \ud83d\udd17 **Support for enums, optional types, and unions** - Properly extract and display union types\n- \u2699\ufe0f **Customizable output formatting** - Indentation, compact mode, and more\n- \ud83c\udfa8 **Rich Default Values** - Automatically shows default values in human-readable comments\n- \ud83d\udccf **Smart Constraints** - Displays field constraints (length, range, patterns) in clear language\n- \u2705 **Clear Field Status** - Explicit required/optional marking\n- \ud83d\udcda **Rich Examples** - Inline examples and documentation for better LLM understanding\n- \ud83d\udd00 **Advanced Union Types** - Full support for allOf, not constraints, and discriminated unions\n- \ud83d\udd22 **Advanced Arrays** - Contains constraints, minContains/maxContains, and enhanced tuple support\n\n\n\n## Quick Start\n\nView the [demo](demo.md) for more examples and features!\n\n```python\nfrom pydantic import BaseModel\nfrom schellma import schellma\nimport openai\n\nclass TaskRequest(BaseModel):\n    title: str\n    priority: int\n    tags: list[str]\n    due_date: str | None = None\n\n# Generate schema for LLM prompt\nschema = schellma(TaskRequest)\n\n# Add the scheLLMa schema to the prompt\nprompt = f\"\"\"\nPlease create a task with the following structure:\n\n{schema}\n\"\"\"\nprint(prompt)\n\n# Use with your favorite LLM API\ncompletion = openai.chat.completions.create(\n    model=\"gpt-4.1-mini\",\n    messages=[{\n        \"role\": \"user\",\n        \"content\": prompt\n    }]\n)\n\ncontent = completion.choices[0].message.content\nprint(content)\n\ntask = TaskRequest.model_validate_json(clean_content(content))\nprint(task)\n# TaskRequest(title='Task 1', priority=1, tags=['tag1', 'tag2'], due_date=None)\n```\n\n### Using the new openai chat.completions.**parse** API\n\n```python\n# or directly parse with openai sdk\ncompletion = openai.chat.completions.parse(\n    model=\"gpt-4.1-mini\",\n    messages=[{\n        \"role\": \"user\",\n        \"content\": prompt\n    }]\n)\ntask = completion.choices[0].message.parsed\nprint(task)\n# TaskRequest(title='Task 1', priority=1, tags=['tag1', 'tag2'], due_date=None)\n```\n\n### Using the new openai Responses API\n\n```python\nclass CalendarEvent(BaseModel):\n    name: str\n    date: str\n    participants: list[str]\n\nschema = schellma(CalendarEvent)\n\nresponse = openai.responses.parse(\n    model=\"gpt-4o-2024-08-06\",\n    input=[\n        # Make sure to include the schema in your prompt\n        {\"role\": \"system\", \"content\": f\"Extract the event information. {schema}\"},\n        {\n            \"role\": \"user\",\n            \"content\": \"Alice and Bob are going to a science fair on Friday.\",\n        },\n    ],\n    text_format=CalendarEvent,\n)\n\nevent = response.output_parsed\nprint(event)\n# CalendarEvent(name='Alice and Bob are going to a science fair on Friday.', date='Friday', participants=['Alice', 'Bob'])\n```\n\n\n\n## Installation\n\n```bash\npip install schellma\n```\n\nOr using uv:\n\n```bash\nuv add schellma\n```\n\nInstall from github\n\n```bash\nuv add git+https://github.com/andrader/schellma.git\n```\n\n\n### Comparison with JSON Schema\n\n**JSON Schema (verbose, token-heavy):**\n\n```json\n{\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": { \"type\": \"string\" },\n    \"age\": { \"type\": \"integer\" },\n    \"email\": { \"type\": [\"string\", \"null\"], \"default\": null }\n  },\n  \"required\": [\"name\", \"age\"],\n  \"additionalProperties\": false\n}\n```\n\n**scheLLMa (clean, token-efficient):**\n\n```typescript\n{\n    \"name\": string,\n    \"age\": int,\n    \"email\": string | null,\n}\n```\n\n## Advanced Usage with Type Definitions\n\n```python\nfrom pydantic import BaseModel\nfrom typing import List, Optional\nfrom schellma import schellma\n\nclass Address(BaseModel):\n    street: str\n    city: str\n    country: str\n\nclass User(BaseModel):\n    name: str\n    age: int\n    addresses: List[Address]\n    primary_address: Optional[Address] = None\n\n# Generate with separate type definitions\nschema = schellma(User, define_types=True)\nprint(schema)\n```\n\nOutput:\n\n```typescript\nAddress {\n    \"street\": string,\n    \"city\": string,\n    \"country\": string,\n}\n\n{\n    \"name\": string,\n    \"age\": int,\n    \"addresses\": Address[],\n    \"primary_address\": Address | null,\n}\n```\n\n\n\n\n## Examples\n\nView more exemples at [Demo](#demo.md)\n\n### Enum Support\n\n```python\nfrom enum import Enum\nfrom pydantic import BaseModel\n\nclass Status(Enum):\n    ACTIVE = \"active\"\n    INACTIVE = \"inactive\"\n\nclass Task(BaseModel):\n    title: str\n    status: Status\n\nschema = schellma(Task)\n# Output: { \"title\": string, \"status\": \"active\" | \"inactive\" }\n```\n\n### Complex Nested Structures\n\n```python\nfrom pydantic import BaseModel\nfrom typing import Dict, List\n\nclass Tag(BaseModel):\n    name: str\n    color: str\n\nclass Post(BaseModel):\n    title: str\n    content: str\n    tags: List[Tag]\n    metadata: Dict[str, str]\n\nschema = schellma(Post, define_types=True)\n```\n\n\n\n## Development\n\n### Setup\n\n```bash\ngit clone https://github.com/andrader/schellma.git\ncd schellma\nuv sync --dev\n```\n\n### Running Tests\n\n```bash\nuv run python -m pytest\n```\n\n### Type Checking\n\n```bash\nuv run mypy src/schellma/\n```\n\n### Linting\n\n```bash\nuv run ruff check src/schellma/\nuv run ruff format src/schellma/\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n### Development Guidelines\n\n1. Follow the existing code style (enforced by ruff)\n2. Add tests for any new functionality\n3. Update documentation as needed\n4. Ensure all tests pass and type checking succeeds\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Changelog\n\nSee [Changelog](CHANGELOG.md) for the changelog.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Clean, simplified schemas from Pydantic models for LLM prompts - less verbose than JSON Schema",
    "version": "0.4.0",
    "project_urls": {
        "Changelog": "https://andrader.github.io/schellma/CHANGELOG/",
        "Documentation": "https://andrader.github.io/schellma/",
        "Homepage": "https://github.com/andrader/schellma",
        "Issues": "https://github.com/andrader/schellma/issues",
        "Releases": "https://github.com/andrader/schellma/releases",
        "Repository": "https://github.com/andrader/schellma.git"
    },
    "split_keywords": [
        "ai",
        " clean-schema",
        " language-models",
        " llm",
        " prompts",
        " pydantic",
        " schema"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b0d5eccaa3593c1bbd51f81632d4796794a09790348f9dc66a56d44078aa9965",
                "md5": "b44d6daaf8cc99c267f8f824e01ef317",
                "sha256": "f7759c5882d858c92ae731629b35b0378eff2e0da4e8a815fc6c44cdc671e2b3"
            },
            "downloads": -1,
            "filename": "schellma-0.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b44d6daaf8cc99c267f8f824e01ef317",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 23393,
            "upload_time": "2025-10-06T12:40:16",
            "upload_time_iso_8601": "2025-10-06T12:40:16.255094Z",
            "url": "https://files.pythonhosted.org/packages/b0/d5/eccaa3593c1bbd51f81632d4796794a09790348f9dc66a56d44078aa9965/schellma-0.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "47d443712bb2c2aa0cc23a1ac87dba0c644aec2b7c61690d1e2e283ff131c42c",
                "md5": "21606ef2f9da3a4afda19fcb2975f307",
                "sha256": "b16c1cfd33ae78366db39850c0bb5ac91dffd0bc2028291779ad09b4ba95c930"
            },
            "downloads": -1,
            "filename": "schellma-0.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "21606ef2f9da3a4afda19fcb2975f307",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 118099,
            "upload_time": "2025-10-06T12:40:17",
            "upload_time_iso_8601": "2025-10-06T12:40:17.735173Z",
            "url": "https://files.pythonhosted.org/packages/47/d4/43712bb2c2aa0cc23a1ac87dba0c644aec2b7c61690d1e2e283ff131c42c/schellma-0.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-06 12:40:17",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "andrader",
    "github_project": "schellma",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "schellma"
}