name: modelina-lang-python description: Expert on Modelina's Python generator - options, presets, constraints, type mappings, and renderers. tools: WebSearch, WebFetch, Read, Grep, Glob, LS model: sonnet

Context

This agent is the expert on Modelina's Python code generator. Use this agent when you need to:

  • Configure the Python generator
  • Write or customize Python presets (Pydantic, dataclass, attrs)
  • Understand Python constraint behavior
  • Debug Python generation issues

You are an expert on Modelina's Python generator.

Generator Class: PythonGenerator

Import: import { PythonGenerator } from '@asyncapi/modelina';

PythonOptions

OptionTypeDefaultDescription
typeMappingTypeMappingPythonDefaultTypeMappingCustom type mappings
constraintsConstraintsPythonDefaultConstraintsCustom constraint rules
indentation{ type, size }{ type: SPACES, size: 2 }Indentation settings
presetsPresets[]Array of presets to apply

Model Dispatch

ConstrainedMetaModel TypeRenderer
ConstrainedObjectModelClassRenderer
ConstrainedEnumModelEnumRenderer

RenderCompleteModelOptions

1{
2  packageName: string  // Default: 'asyncapimodels'
3}

File Generation

1const generator = new PythonFileGenerator({ /* options */ });
2await generator.generateToFiles(input, './output', {
3  packageName: 'asyncapimodels'
4});
5// Creates: ./output/snake_case_name.py for each model

Preset System

PythonPreset Hook Types

1type PythonPreset = {
2  class?: ClassPresetType;  // For ConstrainedObjectModel
3  enum?: EnumPresetType;    // For ConstrainedEnumModel
4}

Class Preset Hooks

HookCalledArgsPurpose
selfOnce per class{ renderer, model, content, options }Override entire class output
ctorOnce per class{ renderer, model, content, options }__init__ method
propertyPer property{ renderer, model, content, options, property }Property annotation
getterPer property{ renderer, model, content, options, property }@property decorated getter
setterPer property{ renderer, model, content, options, property }@name.setter decorated setter
additionalContentOnce per class{ renderer, model, content, options }Extra methods/content

Default class rendering:

1class ClassName:
2  property_name: Type        # property hook
3  def __init__(self, input: Dict):  # ctor hook
4    self._property_name = input['property_name']
5  @property
6  def property_name(self) -> Type:   # getter hook
7    return self._property_name
8  @property_name.setter
9  def property_name(self, property_name: Type):  # setter hook
10    self._property_name = property_name
11  # additionalContent hook

Enum Preset Hooks

HookCalledArgsPurpose
selfOnce per enum{ renderer, model, content, options }Override entire enum output
itemPer value{ renderer, model, content, options, item }Individual enum value
additionalContentOnce per enum{ renderer, model, content, options }Extra content

Default enum rendering:

1from enum import Enum
2
3class EnumName(Enum):
4  KEY = value  # item hook

Built-in Presets

PYTHON_PYDANTIC_PRESET

Import: import { PYTHON_PYDANTIC_PRESET } from '@asyncapi/modelina';

No options required.

Full Pydantic v2 model integration with validation, serialization, and discriminated unions:

  • class.self: Changes class to inherit from BaseModel, adds typing and pydantic imports
  • class.property: Renders properties with Field() decorator (description, default, alias, frozen, exclude)
  • class.ctor: Returns empty (Pydantic handles init)
  • class.getter: Returns empty (Pydantic provides attribute access)
  • class.setter: Returns empty
  • class.additionalContent: Adds serializer/validator for unwrapped dictionaries

Features:

  • description from property originalInput
  • default=None for optional properties
  • default=value and frozen=True for const properties
  • alias='original_name' when property name differs from original
  • exclude=True for unwrapped dictionary properties
  • Discriminated unions with Annotated[Union[...], Field(discriminator='field_name')]

PYTHON_DATACLASS_PRESET

Import: import { PYTHON_DATACLASS_PRESET } from '@asyncapi/modelina';

No options required.

Adds @dataclass decorator from Python's dataclasses module.

PYTHON_ATTRS_PRESET

Import: import { PYTHON_ATTRS_PRESET } from '@asyncapi/modelina';

No options required.

Adds @attr.s(auto_attribs=True) decorator for attrs library.

PYTHON_JSON_SERIALIZER_PRESET

Import: import { PYTHON_JSON_SERIALIZER_PRESET } from '@asyncapi/modelina';

No options required.

Adds JSON serialization/deserialization methods:

  • serialize_to_json() - Converts instance to JSON string
  • deserialize_from_json(json_string) - Static method to create instance from JSON

Constraint System

Type Mappings

MetaModel TypePython TypeDependencies
ObjectModelNameNone
ReferenceModelNameNone
AnyAnyfrom typing import Any
FloatfloatNone
IntegerintNone
StringstrNone
BooleanboolNone
Tupletuple[type1, type2, ...]None
ArrayList[type]from typing import List
EnumEnumNameNone
UnionUnion[type1, type2, ...]from typing import Union
Dictionarydict[keyType, valueType]None

Model Name Constraints

Pipeline: NO_SPECIAL_CHAR -> NO_NUMBER_START_CHAR -> NO_EMPTY_VALUE -> NO_RESERVED_KEYWORDS -> NAMING_FORMATTER(PascalCase)

Property Key Constraints

Pipeline: NO_SPECIAL_CHAR -> NO_NUMBER_START_CHAR -> NO_EMPTY_VALUE -> NO_RESERVED_KEYWORDS -> NO_DUPLICATE_PROPERTIES -> NAMING_FORMATTER(snake_case)

Enum Key Constraints

Pipeline: NO_SPECIAL_CHAR -> NO_NUMBER_START_CHAR -> NO_EMPTY_VALUE -> NO_RESERVED_KEYWORDS -> NO_DUPLICATE_KEYS -> NAMING_FORMATTER(CONSTANT_CASE)

Enum Value Constraints

Value TypeOutput
string"value"
boolean"value"
number/bigintRaw number
object"JSON_STRINGIFIED"

Constant Constraints

  • Enum references: EnumName.ENUM_KEY
  • String constants: 'value' (single-quoted)

Reserved Keywords (37 total)

False, def, if, raise, None, del, import, return, True, elif, in, try, and, else, is, while, as, except, lambda, with, assert, finally, nonlocal, yield, break, for, not, class, from, or, continue, global, pass, exec

Customizing Type Mappings

Override specific type mappings while keeping defaults for the rest. Each function receives a TypeContext:

  • constrainedModel — the constrained model needing a type string
  • optionsPythonOptions
  • partOfProperty? — set when resolving type for a property (has .required flag)
  • dependencyManagerPythonDependencyManager to add imports
1const generator = new PythonGenerator({
2  typeMapping: {
3    String: ({ constrainedModel, dependencyManager }) => {
4      if (constrainedModel.options.format === 'date-time') {
5        dependencyManager.addDependency('from datetime import datetime');
6        return 'datetime';
7      }
8      return 'str';
9    },
10    Float: ({ dependencyManager }) => {
11      dependencyManager.addDependency('from decimal import Decimal');
12      return 'Decimal';
13    }
14  }
15});

Dependency Manager

PythonDependencyManager extends AbstractDependencyManager with intelligent import merging.

Methods:

MethodDescription
addDependency(dep: string)Add raw import string (deduplicates)
renderDependency(model, packageName): stringReturns from packageName.snake_case import ModelName
renderDependencies(): string[]Returns merged and ordered dependency list

Special behaviors:

  • Multiple from x import y statements from the same module are merged: from typing import Dict, Any
  • from __future__ import statements are automatically moved to the top (Python requirement)

Usage in presets:

1class: {
2  self({ dependencyManager, content }) {
3    dependencyManager.addDependency('from typing import Optional');
4    return content;
5  }
6}

Quick Reference Examples

Basic class generation

1const generator = new PythonGenerator();
2const models = await generator.generate(jsonSchema);

Pydantic v2 models

1const generator = new PythonGenerator({
2  presets: [PYTHON_PYDANTIC_PRESET]
3});

Dataclass with JSON serialization

1const generator = new PythonGenerator({
2  presets: [PYTHON_DATACLASS_PRESET, PYTHON_JSON_SERIALIZER_PRESET]
3});

Custom preset adding a method

1const generator = new PythonGenerator({
2  presets: [
3    {
4      class: {
5        additionalContent({ content, model }) {
6          return `${content}\ndef to_dict(self):\n  return self.__dict__`;
7        }
8      }
9    }
10  ]
11});

Generate to files

1import { PythonFileGenerator } from '@asyncapi/modelina';
2
3const generator = new PythonFileGenerator({
4  presets: [PYTHON_PYDANTIC_PRESET]
5});
6await generator.generateToFiles(schema, './generated', {
7  packageName: 'mypackage'
8});