Files
gh-epieczko-betty/skills/api.generatemodels/SKILL.md
2025-11-29 18:26:08 +08:00

7.4 KiB

api.generate-models

Overview

api.generate-models generates type-safe models from OpenAPI and AsyncAPI specifications, enabling shared models between frontend and backend using code generation.

Purpose

Transform API specifications into type-safe code:

  • Generate TypeScript interfaces from OpenAPI schemas
  • Generate Python dataclasses/Pydantic models
  • Generate Java classes, Go structs, C# classes
  • Single source of truth: the API specification
  • Automatic synchronization when specs change

Usage

Basic Usage

python skills/api.generate-models/modelina_generate.py <spec_path> <language> [options]

Parameters

Parameter Required Description Default
spec_path Yes Path to API spec file -
language Yes Target language -
--output-dir No Output directory src/models
--package-name No Package/module name -

Supported Languages

Language Extension Status
typescript .ts Supported
python .py Supported
java .java 🚧 Planned
go .go 🚧 Planned
csharp .cs 🚧 Planned
rust .rs 🚧 Planned

Examples

Example 1: Generate TypeScript Models

python skills/api.generate-models/modelina_generate.py \
  specs/user-service.openapi.yaml \
  typescript \
  --output-dir=src/models/user-service

Generated files:

src/models/user-service/
├── User.ts
├── UserCreate.ts
├── UserUpdate.ts
├── Pagination.ts
└── Problem.ts

Example TypeScript output:

// src/models/user-service/User.ts
export interface User {
  /** Unique identifier */
  user_id: string;
  /** Creation timestamp */
  created_at: string;
  /** Last update timestamp */
  updated_at?: string;
}

// src/models/user-service/Pagination.ts
export interface Pagination {
  /** Number of items per page */
  limit: number;
  /** Number of items skipped */
  offset: number;
  /** Total number of items available */
  total: number;
}

Example 2: Generate Python Models

python skills/api.generate-models/modelina_generate.py \
  specs/user-service.openapi.yaml \
  python \
  --output-dir=src/models/user_service

Generated files:

src/models/user_service/
└── models.py

Example Python output:

# src/models/user_service/models.py
from pydantic import BaseModel, Field
from typing import Optional
from datetime import datetime
from uuid import UUID

class User(BaseModel):
    """User model"""
    user_id: UUID = Field(..., description="Unique identifier")
    created_at: datetime = Field(..., description="Creation timestamp")
    updated_at: Optional[datetime] = Field(None, description="Last update timestamp")

class Pagination(BaseModel):
    """Pagination metadata"""
    limit: int = Field(..., description="Number of items per page")
    offset: int = Field(..., description="Number of items skipped")
    total: int = Field(..., description="Total number of items available")

Example 3: Generate for Multiple Languages

# TypeScript for frontend
python skills/api.generate-models/modelina_generate.py \
  specs/user-service.openapi.yaml \
  typescript \
  --output-dir=frontend/src/models

# Python for backend
python skills/api.generate-models/modelina_generate.py \
  specs/user-service.openapi.yaml \
  python \
  --output-dir=backend/app/models

Code Generators Used

The skill uses multiple code generation approaches:

1. datamodel-code-generator (Primary)

Best for: OpenAPI specs → Python/TypeScript Installation: pip install datamodel-code-generator

Generates:

  • Python: Pydantic v2 models with type hints
  • TypeScript: Type-safe interfaces
  • Validates schema during generation

2. Simple Built-in Generator (Fallback)

Best for: Basic models when external tools not available Installation: None required

Generates:

  • Python: dataclasses
  • TypeScript: interfaces
  • Basic but reliable

3. Modelina (Future)

Best for: AsyncAPI specs, multiple languages Installation: npm install -g @asyncapi/modelina Status: Planned

Output

Success Response

{
  "status": "success",
  "data": {
    "models_path": "src/models/user-service",
    "files_generated": [
      "src/models/user-service/User.ts",
      "src/models/user-service/UserCreate.ts",
      "src/models/user-service/Pagination.ts",
      "src/models/user-service/Problem.ts"
    ],
    "model_count": 4,
    "generator_used": "datamodel-code-generator"
  }
}

Integration with Workflows

# workflows/api_first_development.yaml
steps:
  - skill: api.define
    args:
      - "user-service"
      - "openapi"
    output: spec_path

  - skill: api.validate
    args:
      - "{spec_path}"
      - "zalando"
    required: true

  - skill: api.generate-models
    args:
      - "{spec_path}"
      - "typescript"
      - "--output-dir=frontend/src/models"

  - skill: api.generate-models
    args:
      - "{spec_path}"
      - "python"
      - "--output-dir=backend/app/models"

Integration with Hooks

Auto-regenerate models when specs change:

python skills/hook.define/hook_define.py \
  on_file_save \
  "python betty/skills/api.generate-models/modelina_generate.py {file_path} typescript --output-dir=src/models" \
  --pattern="specs/*.openapi.yaml" \
  --blocking=false \
  --description="Auto-regenerate TypeScript models when OpenAPI specs change"

Benefits

For Developers

  • Type safety: Catch errors at compile time, not runtime
  • IDE autocomplete: Full IntelliSense/autocomplete support
  • No manual typing: Models generated automatically
  • Always in sync: Regenerate when spec changes

For Teams

  • Single source of truth: API spec defines types
  • Frontend/backend alignment: Same types everywhere
  • Reduced errors: Type mismatches caught early
  • Faster development: No manual model creation

For Organizations

  • Consistency: All services use same model generation
  • Maintainability: Update spec → regenerate → done
  • Documentation: Types are self-documenting
  • Quality: Generated code is tested and reliable

Dependencies

Required

  • PyYAML: For YAML parsing (pip install pyyaml)

Optional (Better Output)

  • datamodel-code-generator: For high-quality Python/TypeScript (pip install datamodel-code-generator)
  • Node.js + Modelina: For AsyncAPI and more languages (npm install -g @asyncapi/modelina)

Examples with Real Specs

Using the user-service spec from Phase 1:

# Generate TypeScript
python skills/api.generate-models/modelina_generate.py \
  specs/user-service.openapi.yaml \
  typescript

# Output:
{
  "status": "success",
  "data": {
    "models_path": "src/models",
    "files_generated": [
      "src/models/User.ts",
      "src/models/UserCreate.ts",
      "src/models/UserUpdate.ts",
      "src/models/Pagination.ts",
      "src/models/Problem.ts"
    ],
    "model_count": 5
  }
}

See Also

Version

0.1.0 - Initial implementation with TypeScript and Python support