Yet Another Interface File - a lightweight schema language and multi-target code generator
Project description
YAIF · Yet Another Interface File
Define your data model once. Generate everything else.
YAIF is a lightweight, zero-dependency schema language and multi-target code generator. Write a single .yaif file describing your interfaces and enums, then generate:
- 🐍 Python dataclasses & enums
- 📘 TypeScript interfaces & enums
- 📋 JSON Schema (draft-07)
- 🌐 Interactive HTML CRUD application (no build step)
- 💬 Discord-formatted output with rich embed support
All from the same source of truth.
📦 Installation
git clone https://github.com/SamTechAV/Yet-Another-Interface-File.git
cd yaif
pip install -e .
YAIF uses only the Python standard library—no external dependencies required.
🚀 Quick Start (60 seconds)
1️⃣ Create schema.yaif
[config]
title: My App
description: A sample schema
[interface User]
id: int
name: string @label="Full Name"
email: string @placeholder="user@example.com"
admin: bool = false
[enum Role]
admin, editor, viewer
2️⃣ Generate your code
# Python dataclasses
python -m yaif schema.yaif -t python -o models.py
# TypeScript interfaces
python -m yaif schema.yaif -t typescript -o types.ts
# Interactive HTML prototype
python -m yaif schema.yaif -t html -o app.html
# JSON Schema
python -m yaif schema.yaif -t jsonschema -o schema.json
3️⃣ Open app.html in your browser—instant CRUD UI with zero configuration.
✨ Why YAIF?
| ✅ Feature | 💡 Benefit |
|---|---|
| Single source of truth | Define once, generate for multiple platforms |
| Zero runtime deps | Pure stdlib—no node_modules, no pip install for users |
| Instant HTML UI | Generated forms work immediately in any browser |
| Type-safe | Strong typing across Python, TypeScript, JSON Schema |
| Live reload | --watch mode regenerates on file changes |
| Discord integration | Send formatted output directly to channels |
| Inheritance & grouping | Build complex schemas with clean organization |
| Production-grade | Validates circular dependencies, proper defaults |
📖 The .yaif Format
A .yaif file consists of three block types:
1. [config] — Application Metadata & Theming
[config]
title: Store Admin
description: E-commerce management
accent: "#007aff"
background: "#f2f2f7"
surface: "#ffffff"
ink: "#1c1c1e"
muted: "#8e8e93"
font: "'Inter', system-ui, sans-serif"
mono: "'SF Mono', 'Fira Code', monospace"
| Key | Purpose | Default |
|---|---|---|
title |
App name in HTML UI | YAIF App |
description |
Subtitle | (empty) |
accent |
Primary color | #c84b31 |
accent2 |
Secondary color | #2a6496 |
background |
Page background | #f5f0e8 |
surface |
Card/panel background | #ffffff |
ink |
Primary text | #1a1a2e |
muted |
Secondary text | #8a8070 |
font |
Body font stack | 'Fraunces', Georgia, serif |
mono |
Monospace font | 'DM Mono', monospace |
font_url |
Google Fonts override | (DM Mono + Fraunces) |
2. [interface] — Data Structures
[interface Post extends BaseEntity]
title: string @label="Title" @placeholder="Enter title"
body: string @rows=8 @wide
status: PostStatus @label="Status" @order=10
tags: list[string] @label="Tags" @hint="Comma-separated"
author: optional[Author] @label="Author"
created: string = now() @readonly @group="Meta"
Field syntax: name: type [= default] [@annotation]
Supported types:
| YAIF Type | Python | TypeScript | JSON Schema |
|---|---|---|---|
string |
str |
string |
{"type": "string"} |
int |
int |
number |
{"type": "integer"} |
float |
float |
number |
{"type": "number"} |
bool |
bool |
boolean |
{"type": "boolean"} |
list[T] |
list[T] |
T[] |
{"type": "array", "items": ...} |
optional[T] |
Optional[T] |
T | null |
{"oneOf": [T, null]} |
dict[K,V] |
dict[K,V] |
Record<K,V> |
{"type": "object", "additionalProperties": V} |
InterfaceName |
class reference | type reference | {"$ref": "#/$defs/InterfaceName"} |
EnumName |
Enum subclass |
enum |
{"$ref": "#/$defs/EnumName"} |
3. [enum] — Enumerations
[enum PostStatus]
draft, published, archived
[enum Priority]
low = 1, normal = 2, high = 3, urgent = 4
🏷️ Annotations
Place annotations after the type/default using @key or @key="value" syntax.
HTML Generator Annotations
| Annotation | Effect |
|---|---|
@label="Text" |
Custom field label (overrides name) |
@placeholder="Text" |
Input placeholder text |
@hint="Text" |
Helper text below field |
@hidden |
Exclude from generated UI/output |
@readonly |
Render as disabled/non-editable |
@wide |
Span full form width |
@rows=N |
Render as textarea with N rows |
@group="Name" |
Group fields under collapsible section |
@order=N |
Override field display order |
@default="value" |
Alternative to = value syntax |
Discord Annotations
| Annotation | Effect |
|---|---|
@discord=table|kv|list |
Render mode for this interface |
@discord_title="Name" |
Override section heading |
@discord_icon="📊" |
Emoji prefix on heading |
@discord_width=N |
Min column width (table mode) |
@label="Text" |
Column/key header text |
@hidden |
Skip field in output |
Embed Annotations (when using --embed)
| Annotation | Effect |
|---|---|
@embed_color="#rrggbb" |
Sidebar color for this embed |
@embed_url="https://..." |
Make title a hyperlink |
@embed_footer="text" |
Custom footer text |
@embed_thumbnail |
Use field value as thumbnail URL |
@embed_image |
Use field value as embed image |
@embed_timestamp |
Use field value as ISO 8601 timestamp |
@embed_inline |
🔄 Inheritance
Interfaces can extend other interfaces—all parent fields are inherited.
[interface BaseEntity]
id: int
created_at: string
[interface Post extends BaseEntity]
title: string
body: string
Circular inheritance is detected and raises a parse error. Multiple inheritance levels are supported.
⚙️ Generators
Run any generator with -t <target>. Pipe to stdout or write with -o <file>.
🐍 Python
Generates @dataclass classes and Enum subclasses.
python -m yaif schema.yaif -t python -o models.py
from __future__ import annotations
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
class PostStatus(Enum):
DRAFT = "draft"
PUBLISHED = "published"
@dataclass
class Post:
title: str
body: str
status: str = "draft"
tags: list[str] = field(default_factory=list)
Note: Fields without defaults appear before fields with defaults (required by Python dataclasses).
📘 TypeScript
Generates export interface and export enum declarations.
python -m yaif schema.yaif -t typescript -o types.ts
export enum PostStatus {
draft = "draft",
published = "published",
}
export interface Post extends BaseEntity {
title: string;
body: string;
status?: PostStatus;
tags: string[];
}
📋 JSON Schema
Generates draft-07 JSON Schema with $definitions. Supports $ref and allOf for inheritance.
python -m yaif schema.yaif -t jsonschema -o schema.json
🌐 HTML (Instant CRUD UI)
Generates a fully self-contained, single-file HTML application. No build step, no server—just open in a browser.
python -m yaif schema.yaif -t html -o app.html
Features:
- 📑 A tab per interface
- 📝 Forms with appropriate inputs (text, number, checkbox, select, textarea)
- 🔄 Nested forms for interface fields, dynamic lists & dicts
- ➕➖ Add, edit, delete, export records as JSON
- 🎨 Full theming from
[config]block - 📱 Responsive design
- ⚡ Client-side only—no backend needed
💬 Discord Output
Generates formatted text with box-drawing characters for clean Discord rendering.
python -m yaif discord.yaif -t discord
Render modes:
| Mode | Default | Example |
|---|---|---|
table |
✅ | Box-drawing table with column headers |
kv |
Aligned key: value pairs |
|
list |
Bulleted list |
📤 Discord Webhook
Send output directly to a Discord channel from the terminal.
# Send plain text
python -m yaif discord.yaif -t discord --send --webhook-url https://discord.com/api/webhooks/...
# Send as rich embeds
python -m yaif discord.yaif -t discord --send --embed
Store the webhook URL in [config] to avoid passing it every time:
[config]
webhook_url: https://discord.com/api/webhooks/...
webhook_username: My Bot
embed_mode: false
embed_color: #5865F2
Limitation: Discord allows max 10 embeds per message—YAIF auto-batches larger payloads.
👁️ File Watcher
Watch a .yaif file and regenerate output automatically on every save:
python -m yaif schema.yaif -t typescript -o types.ts --watch
Uses simple polling (no external deps). Press Ctrl+C to stop.
🎯 CLI Reference
python -m yaif <file> [options]
Positional:
file Path to the .yaif file
Generator options:
-t, --target Target: python, typescript, jsonschema, html, discord
-o, --output Write to file (default: stdout)
--validate-only Parse and validate without generating
-w, --watch Watch for changes and regenerate
Discord webhook options:
--send Send to Discord webhook
--webhook-url URL Webhook URL (overrides config)
--embed Send as rich embeds
--webhook-username NAME Override bot display name
--webhook-avatar URL Override bot avatar URL
🗂️ Project Structure
yaif/
├── __main__.py CLI entrypoint
├── models.py Data classes: YAIFField, YAIFInterface, YAIFEnum, YIFConfig
├── parser.py YAIFParser — tokenizes & validates .yaif source
├── discord_webhook.py Discord embed builder + HTTP sender
├── watcher.py File watcher (polling-based)
└── generators/
├── base.py BaseGenerator abstract class
├── python.py Python dataclass generator
├── typescript.py TypeScript interface generator
├── jsonschema.py JSON Schema draft-07 generator
├── html.py Self-contained HTML CRUD generator
└── discord.py Discord text formatter
📚 Example Files
Explore real-world usage in the examples/ directory:
| Example | Description |
|---|---|
ecommerce.yaif |
Full e-commerce schema: products, orders, customers, reviews |
clinic.yaif |
Medical clinic patient & appointment system |
project_tracker.yaif |
Project & task management |
jobs.yaif |
Job board with postings & applications |
smart_home.yaif |
IoT device & automation dashboard |
rpg.yaif |
RPG game entities (characters, items, quests) |
ci_discord.yaif |
Discord notifications for CI/CD |
🤝 Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure
python -m yaif --validate-onlypasses on example files - Submit a pull request
See CONTRIBUTING.md for detailed guidelines.
📄 License
MIT License—see LICENSE.txt for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file yaif-0.1.0-py3-none-any.whl.
File metadata
- Download URL: yaif-0.1.0-py3-none-any.whl
- Upload date:
- Size: 34.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
83de7bf2e5272b70ef7b10fc506b148ebb2727712035282164920aa25b361869
|
|
| MD5 |
b2acb08eff5aef82e015e6627fa0135f
|
|
| BLAKE2b-256 |
4d8da3650314f5c4c0e3dd5407de0193fb721051194237bf3c3ebd04c9898e7b
|