Code Generators - NinjaStack Docs
Description: Schema-first agentic backend framework documentation

Skip to content

# Code Generators

## Models Generator

## `` models

Generate Pydantic models from EntitySchema definitions.

### `` generate_model

    generate_model(
        entity: EntitySchema, output_dir: Path
    ) -> Path

Generate a Pydantic model file for a single entity.

PARAMETER | DESCRIPTION
--- | ---
`entity` | The entity schema to generate from. TYPE: `EntitySchema`
`output_dir` | Directory to write the generated file into. TYPE: `Path`

RETURNS | DESCRIPTION
--- | ---
`Path` | Path to the generated file.

Source code in `libs/ninja-codegen/src/ninja_codegen/generators/models.py`

    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    def generate_model(entity: EntitySchema, output_dir: Path) -> Path:
        """Generate a Pydantic model file for a single entity.

        Args:
            entity: The entity schema to generate from.
            output_dir: Directory to write the generated file into.

        Returns:
            Path to the generated file.
        """
        env = get_template_env()
        template = env.get_template("model.py.j2")

        content = template.render(
            entity=entity,
            fields_meta=build_fields_meta(entity),
            has_uuid=_has_field_type(entity, "uuid"),
            has_datetime=_has_field_type(entity, "datetime"),
            has_date=_has_field_type(entity, "date"),
            has_constraints=any(f.constraints for f in entity.fields),
        )

        file_path = output_dir / f"{entity.name.lower()}.py"
        write_generated_file(file_path, content)
        return file_path

### `` generate_models

    generate_models(
        entities: list[EntitySchema], output_dir: Path
    ) -> list[Path]

Generate Pydantic models for all entities.

PARAMETER | DESCRIPTION
--- | ---
`entities` | List of entity schemas. TYPE: `list[EntitySchema]`
`output_dir` | Base directory for generated model files. TYPE: `Path`

RETURNS | DESCRIPTION
--- | ---
`list[Path]` | List of paths to generated files.

Source code in `libs/ninja-codegen/src/ninja_codegen/generators/models.py`

    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    def generate_models(entities: list[EntitySchema], output_dir: Path) -> list[Path]:
        """Generate Pydantic models for all entities.

        Args:
            entities: List of entity schemas.
            output_dir: Base directory for generated model files.

        Returns:
            List of paths to generated files.
        """
        models_dir = output_dir / "_generated" / "models"
        paths: list[Path] = []

        # Generate __init__.py that re-exports all models
        init_lines = [
            "# AUTO-GENERATED by ninja-codegen — DO NOT EDIT",
            "",
        ]
        for entity in entities:
            path = generate_model(entity, models_dir)
            paths.append(path)
            init_lines.append(f"from .{entity.name.lower()} import {entity.name}")

        if entities:
            init_lines.append("")
            all_names = ", ".join(repr(e.name) for e in entities)
            init_lines.append(f"__all__ = [{all_names}]")
            init_lines.append("")

        init_path = models_dir / "__init__.py"
        write_generated_file(init_path, "\n".join(init_lines))
        paths.append(init_path)

        return paths

## Agents Generator

## `` agents

Generate DataAgent, DomainAgent, and CoordinatorAgent code from ASD definitions.

### `` generate_data_agent

    generate_data_agent(
        entity: EntitySchema, output_dir: Path
    ) -> Path

Generate a DataAgent file for a single entity.

PARAMETER | DESCRIPTION
--- | ---
`entity` | The entity schema to generate from. TYPE: `EntitySchema`
`output_dir` | Directory to write the generated file into. TYPE: `Path`

RETURNS | DESCRIPTION
--- | ---
`Path` | Path to the generated file.

Source code in `libs/ninja-codegen/src/ninja_codegen/generators/agents.py`

    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    def generate_data_agent(entity: EntitySchema, output_dir: Path) -> Path:
        """Generate a DataAgent file for a single entity.

        Args:
            entity: The entity schema to generate from.
            output_dir: Directory to write the generated file into.

        Returns:
            Path to the generated file.
        """
        env = get_template_env()
        template = env.get_template("data_agent.py.j2")
        content = template.render(entity=entity)

        file_path = output_dir / f"{entity.name.lower()}_agent.py"
        write_generated_file(file_path, content)
        return file_path

### `` generate_domain_agent

    generate_domain_agent(
        domain: DomainSchema, output_dir: Path
    ) -> Path

Generate a DomainAgent file for a single domain.

PARAMETER | DESCRIPTION
--- | ---
`domain` | The domain schema to generate from. TYPE: `DomainSchema`
`output_dir` | Directory to write the generated file into. TYPE: `Path`

RETURNS | DESCRIPTION
--- | ---
`Path` | Path to the generated file.

Source code in `libs/ninja-codegen/src/ninja_codegen/generators/agents.py`

    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    def generate_domain_agent(domain: DomainSchema, output_dir: Path) -> Path:
        """Generate a DomainAgent file for a single domain.

        Args:
            domain: The domain schema to generate from.
            output_dir: Directory to write the generated file into.

        Returns:
            Path to the generated file.
        """
        env = get_template_env()
        template = env.get_template("domain_agent.py.j2")
        content = template.render(domain=domain)

        file_path = output_dir / f"{domain.name.lower()}_agent.py"
        write_generated_file(file_path, content)
        return file_path

### `` generate_coordinator

    generate_coordinator(
        domains: list[DomainSchema], output_dir: Path
    ) -> Path

Generate a CoordinatorAgent file wiring all domain agents.

PARAMETER | DESCRIPTION
--- | ---
`domains` | List of domain schemas to wire together. TYPE: `list[DomainSchema]`
`output_dir` | Directory to write the generated file into. TYPE: `Path`

RETURNS | DESCRIPTION
--- | ---
`Path` | Path to the generated file.

Source code in `libs/ninja-codegen/src/ninja_codegen/generators/agents.py`

    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    def generate_coordinator(domains: list[DomainSchema], output_dir: Path) -> Path:
        """Generate a CoordinatorAgent file wiring all domain agents.

        Args:
            domains: List of domain schemas to wire together.
            output_dir: Directory to write the generated file into.

        Returns:
            Path to the generated file.
        """
        env = get_template_env()
        template = env.get_template("coordinator_agent.py.j2")
        domain_names = [d.name for d in domains]
        content = template.render(domains=domains, domain_names=domain_names)

        file_path = output_dir / "coordinator_agent.py"
        write_generated_file(file_path, content)
        return file_path

### `` generate_agents

    generate_agents(
        entities: list[EntitySchema],
        domains: list[DomainSchema],
        output_dir: Path,
    ) -> list[Path]

Generate all agent files (data + domain + coordinator).

PARAMETER | DESCRIPTION
--- | ---
`entities` | List of entity schemas. TYPE: `list[EntitySchema]`
`domains` | List of domain schemas. TYPE: `list[DomainSchema]`
`output_dir` | Base directory for generated agent files. TYPE: `Path`

RETURNS | DESCRIPTION
--- | ---
`list[Path]` | List of paths to generated files.

Source code in `libs/ninja-codegen/src/ninja_codegen/generators/agents.py`

     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    def generate_agents(
        entities: list[EntitySchema],
        domains: list[DomainSchema],
        output_dir: Path,
    ) -> list[Path]:
        """Generate all agent files (data + domain + coordinator).

        Args:
            entities: List of entity schemas.
            domains: List of domain schemas.
            output_dir: Base directory for generated agent files.

        Returns:
            List of paths to generated files.
        """
        agents_dir = output_dir / "_generated" / "agents"
        paths: list[Path] = []

        # Generate data agents
        init_lines = [
            "# AUTO-GENERATED by ninja-codegen — DO NOT EDIT",
            "",
        ]

        for entity in entities:
            path = generate_data_agent(entity, agents_dir)
            paths.append(path)
            init_lines.append(
                f"from .{entity.name.lower()}_agent import {entity.name.upper()}_ENTITY, {entity.name.lower()}_data_agent"
            )

        # Generate domain agents
        for domain in domains:
            path = generate_domain_agent(domain, agents_dir)
            paths.append(path)
            init_lines.append(
                f"from .{domain.name.lower()}_agent import {domain.name.upper()}_DOMAIN"
                f", create_{domain.name.lower()}_domain_agent"
            )

        # Generate coordinator agent
        if domains:
            path = generate_coordinator(domains, agents_dir)
            paths.append(path)
            init_lines.append("from .coordinator_agent import create_coordinator")

        if entities or domains:
            init_lines.append("")

        init_path = agents_dir / "__init__.py"
        write_generated_file(init_path, "\n".join(init_lines))
        paths.append(init_path)

        return paths

## GraphQL Generator

## `` graphql

Generate Strawberry GraphQL types and resolvers from EntitySchema definitions.

### `` generate_gql_type

    generate_gql_type(
        entity: EntitySchema, output_dir: Path
    ) -> Path

Generate GraphQL type and resolver stubs for a single entity.

PARAMETER | DESCRIPTION
--- | ---
`entity` | The entity schema to generate from. TYPE: `EntitySchema`
`output_dir` | Directory to write the generated file into. TYPE: `Path`

RETURNS | DESCRIPTION
--- | ---
`Path` | Path to the generated file.

Source code in `libs/ninja-codegen/src/ninja_codegen/generators/graphql.py`

    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    def generate_gql_type(entity: EntitySchema, output_dir: Path) -> Path:
        """Generate GraphQL type and resolver stubs for a single entity.

        Args:
            entity: The entity schema to generate from.
            output_dir: Directory to write the generated file into.

        Returns:
            Path to the generated file.
        """
        env = get_template_env()
        template = env.get_template("gql_type.py.j2")

        content = template.render(
            entity=entity,
            fields_meta=build_fields_meta(entity),
            has_uuid=_has_field_type(entity, "uuid"),
            has_datetime=_has_field_type(entity, "datetime"),
            has_date=_has_field_type(entity, "date"),
        )

        file_path = output_dir / f"{entity.name.lower()}_gql.py"
        write_generated_file(file_path, content)
        return file_path

### `` generate_graphql

    generate_graphql(
        entities: list[EntitySchema], output_dir: Path
    ) -> list[Path]

Generate GraphQL types and resolvers for all entities.

PARAMETER | DESCRIPTION
--- | ---
`entities` | List of entity schemas. TYPE: `list[EntitySchema]`
`output_dir` | Base directory for generated GQL files. TYPE: `Path`

RETURNS | DESCRIPTION
--- | ---
`list[Path]` | List of paths to generated files.

Source code in `libs/ninja-codegen/src/ninja_codegen/generators/graphql.py`

    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    def generate_graphql(entities: list[EntitySchema], output_dir: Path) -> list[Path]:
        """Generate GraphQL types and resolvers for all entities.

        Args:
            entities: List of entity schemas.
            output_dir: Base directory for generated GQL files.

        Returns:
            List of paths to generated files.
        """
        gql_dir = output_dir / "_generated" / "graphql"
        paths: list[Path] = []

        init_lines = [
            "# AUTO-GENERATED by ninja-codegen — DO NOT EDIT",
            "",
        ]

        for entity in entities:
            path = generate_gql_type(entity, gql_dir)
            paths.append(path)
            init_lines.append(
                f"from .{entity.name.lower()}_gql import "
                f"{entity.name}Type, {entity.name}Input, "
                f"{entity.name}Query, {entity.name}Mutation"
            )

        if entities:
            init_lines.append("")

        init_path = gql_dir / "__init__.py"
        write_generated_file(init_path, "\n".join(init_lines))
        paths.append(init_path)

        return paths

## App Shell Generator

## `` apps

Generate thin FastAPI app shells.

### `` generate_app_shell

    generate_app_shell(
        project_name: str, output_dir: Path
    ) -> Path

Generate a FastAPI app shell.

PARAMETER | DESCRIPTION
--- | ---
`project_name` | Name of the project. TYPE: `str`
`output_dir` | Base directory for generated app files. TYPE: `Path`

RETURNS | DESCRIPTION
--- | ---
`Path` | Path to the generated file.

Source code in `libs/ninja-codegen/src/ninja_codegen/generators/apps.py`

    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    def generate_app_shell(project_name: str, output_dir: Path) -> Path:
        """Generate a FastAPI app shell.

        Args:
            project_name: Name of the project.
            output_dir: Base directory for generated app files.

        Returns:
            Path to the generated file.
        """
        env = get_template_env()
        template = env.get_template("app_shell.py.j2")

        content = template.render(project_name=project_name)

        apps_dir = output_dir / "_generated" / "app"
        file_path = apps_dir / "main.py"
        write_generated_file(file_path, content)

        # Write __init__.py
        init_content = "# AUTO-GENERATED by ninja-codegen — DO NOT EDIT\n\nfrom .main import app\n\n__all__ = ['app']\n"
        init_path = apps_dir / "__init__.py"
        write_generated_file(init_path, init_content)

        return file_path