agentsclimarketplace

Generate python

Skill HaibaraAiAPTX/frontend-openapi-skills/skills/generate-python

Generate Python code from OpenAPI via aptx-ft, including Pydantic models, sync API functions, and OpenAI function-calling tools.json. Use when user wants: (1) to generate Python client code from OpenAPI/Swagger, (2) Pydantic v2 data models from API schemas, (3) sync API function wrappers with RequestSpec, (4) OpenAI function-calling tools.json, (5) Python code generation targeting aptx-api-core runtime, (6) track generated files with manifest, (7) preview changes before generation. Do NOT use for TypeScript code generation — use generate-artifacts or generate-models instead.From its SKILL.md

Install
npx -y skills add HaibaraAiAPTX/frontend-openapi-skills --skill generate-python

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

10.9 KB, as published. Nobody here has run it

Python Code Generation from OpenAPI

Generate Python (Pydantic models + sync API functions + tools.json) from OpenAPI via aptx-ft CLI.

Contents

Prerequisites

# CLI tool (monorepo)
pnpm add -D @aptx/frontend-tk-cli

# Python runtime dependencies (install in the Python project)
pip install aptx-api-core pydantic

The Python codegen plugin (@aptx/frontend-tk-plugin-python) must be loaded. In a monorepo where the plugin is a workspace dependency of the CLI, it is auto-discovered.

Command Overview

CommandPurposeOutput
python modelGenerate Pydantic v2 model classesmodels/*.py
python functionsGenerate spec + sync function wrappersspec/**/*.py + functions/**/*.py
python toolsGenerate OpenAI function-calling JSONtools.json

Dependency: python functions generates spec files that reference models. Run python model first if you need model imports.

Parameter Reference

All paths are relative to working directory (project root).

Common Options (all three commands)

ParameterRequiredDescription
-i, --inputYesOpenAPI file path (e.g., ./openapi.json)
-o, --outputYesOutput directory (e.g., ./src/api)
--no-manifestNoDisable manifest tracking (default: false)
--manifest-dirNoCustom manifest directory (default: .generated)
--dry-runNoPreview mode without updating manifest (default: false)

Additional Options for python functions

ParameterRequiredDescription
--model-modeNorelative (same project) or package (monorepo)
--model-pathNoPath or package name for model imports

Note: relative 会按“当前生成文件 -> 模型目录”计算 Python 包相对导入;package 会直接使用传入的 Python 包路径。

Model Source Decision

Status: Implemented. 同包场景会生成显式包相对导入(如 from ...models.UserDto import UserDto),跨包场景可用 --model-mode package --model-path my_package.models。

Is the models directory inside the same Python package where functions are generated?
├── YES → --model-mode relative --model-path ./models        (planned)
└── NO  → --model-mode package --model-path my_package.models (planned)

Discovery Phase — MANDATORY FIRST STEP

Before executing any generation command, discover the actual project configuration.

Checklist

# 1. Locate OpenAPI spec
ls ./openapi.json ./swagger.json ./docs/openapi.yaml 2>/dev/null

# 2. Check Python project structure
ls pyproject.toml setup.py setup.cfg 2>/dev/null

# 3. Identify output directories
ls -d src/*/ 2>/dev/null

# 4. Check existing generated code
ls ./src/api/models/*.py 2>/dev/null || echo "no models yet"
ls ./src/api/spec/*.py 2>/dev/null || echo "no specs yet"

Critical Rules

NeverAlways
Guess package name from directoryRead pyproject.toml to get actual package name
Assume model import pathsVerify the Python module path is importable
Skip checking existing filesCheck if output directory already has content

Workflow

  1. Discovery — Read project files, find OpenAPI spec, identify output paths
  2. Check output directory — determine if regeneration is needed
  3. Confirm with user — output dir, model-mode/model-path settings
  4. Execute — Show command, get approval, run

Execution Order

# Step 1: Generate models first
pnpm exec aptx-ft python model -i ./openapi.json -o ./src/api

# Step 2: Generate functions (references models)
pnpm exec aptx-ft python functions -i ./openapi.json -o ./src/api \
  --model-mode relative --model-path ./models

# Step 3: Generate tools.json (optional, for OpenAI function-calling)
pnpm exec aptx-ft python tools -i ./openapi.json -o ./src/api

Monorepo Example

# Models into shared package
pnpm exec aptx-ft python model -i ./openapi.json -o ./packages/api-core-python/src/aptx_api_models

# Functions with package import
pnpm exec aptx-ft python functions -i ./openapi.json -o ./services/web/api \
  --model-mode package --model-path aptx_api_models

Manifest Tracking

The CLI tracks generated files and detects changes between generations.

Generated Manifest Files

<output>/
├── .generated/
│   ├── manifest.json           # Tracks all generated files
│   ├── deletion-report.json    # Machine-readable change report
│   └── deletion-report.md      # Human-readable change report with LLM suggestions
└── generated files...

When to Use Manifest Options

ScenarioCommand
Normal generationOmit manifest options (default)
CI/CD without trackingAdd --no-manifest
Preview changes before applyingAdd --dry-run
Custom manifest locationAdd --manifest-dir ./meta

Output Structure

src/api/
├── .generated/                     # Manifest tracking files
├── models/                         # From python:model
│   ├── __init__.py                 # Auto-generated barrel
│   ├── UserDto.py                  # Pydantic BaseModel
│   ├── Status.py                   # Enum class
│   └── CreateRequest.py            # BaseModel with Field aliases
├── spec/                           # From python:functions
│   ├── __init__.py
│   └── user/
│       ├── __init__.py
│       └── get_info_spec.py        # RequestSpec builder
├── functions/                      # From python:functions
│   ├── __init__.py
│   └── user/
│       ├── __init__.py
│       └── get_info.py             # def wrapper
└── tools.json                      # From python:tools (OpenAI function-calling)

Naming Conventions

Model Naming

OpenAPI SchemaPython Output
UserDtoclass UserDto(BaseModel) — name unchanged
AddAssignmentRequestclass AddAssignmentRequest(BaseModel)

Property Naming

Properties are converted to snake_case with Field(alias=...) preserving the original name:

class UserDto(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    user_name: str = Field(alias="userName")
    created_at: str = Field(alias="createdAt")

Function Naming

Function names are derived from operationId through a normalization pipeline:

operation_name: "getMainAPIUserGetInfo"
  → strip HTTP method prefix: "MainAPIUserGetInfo"
  → strip service prefix:     "UserGetInfo"
  → strip namespace prefix:   "GetInfo"
  → snake_case:               "get_info"

Output:
  spec file:    spec/user/get_info_spec.py  → build_get_info_spec()
  function file: functions/user/get_info.py  → def get_info()

Python reserved words get a trailing underscore: class → class_.

Type Mapping

OpenAPI types are mapped to Python types as follows:

OpenAPI / IR TypePython Type
stringstr
numberfloat
booleanbool
objectdict[str, Any]
array<T>list[T]
$ref to schemaSchema class name directly
union typesA | B
nullableT | None
enum valuesLiteral["value"]

Generated Code Examples

Model File (models/UserDto.py)

from __future__ import annotations
from pydantic import BaseModel, ConfigDict, Field


class UserDto(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    id: str = Field(alias="id")
    user_name: str = Field(alias="userName")
    status: Status | None = Field(default=None, alias="status")

Spec File (spec/user/get_info_spec.py)

from __future__ import annotations
from ...models.get_info_input import GetInfoInput
from aptx_api_core import RequestSpec


def build_get_info_spec(input: GetInfoInput) -> RequestSpec:
    return RequestSpec(
        method="GET",
        path="/MainAPI/User/GetInfo",
        input=input,
    )

Function File (functions/user/get_info.py)

from __future__ import annotations
from ...models.get_info_input import GetInfoInput
from ...models.user_dto import UserDto
from aptx_api_core import get_api_client
from ...spec.user.get_info_spec import build_get_info_spec


def get_info(input: GetInfoInput) -> UserDto:
    return get_api_client().execute(
        build_get_info_spec(input),
        response_type=UserDto,
    )

Tools JSON (tools.json)

[
  {
    "type": "function",
    "function": {
      "name": "userGetInfo",
      "description": "Get user information",
      "parameters": {
        "type": "object",
        "properties": {
          "id": { "type": "string" }
        }
      }
    }
  }
]

Runtime Dependencies

Generated Python code requires at runtime:

# pyproject.toml
[project]
dependencies = [
    "aptx-api-core>=0.1.0",
    "pydantic>=2.0",
]
  • aptx-api-core — sync/async HTTP client runtime with middleware pipeline, error handling, and RequestSpec / ApiClient / Middleware types
  • pydantic v2 — data model base classes (BaseModel, Enum) with validation

Boundaries

This skill handles OpenAPI → Python generation only:

  • Does NOT generate TypeScript code → use generate-artifacts or generate-models
  • Does NOT validate OpenAPI specification correctness
  • Does NOT handle authenticated URL downloads → use download-openapi first
  • Does NOT modify the Python runtime library (aptx-api-core) itself
  • Does NOT create or modify the plugin code (@aptx/frontend-tk-plugin-python)

Related Skills

  • generate-artifacts: TypeScript artifact generation (models + React Query / Vue Query)
  • generate-models: TypeScript model-only generation
  • download-openapi: Fetch OpenAPI spec from URL
  • write-plugin: Write custom CLI plugins

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.