arvalez-openapi 1.4.1

OpenAPI loader and Core IR importer for Arvalez
Documentation

arvalez

Modern OpenAPI client generator with a compiler-style core, typed IR, and WASM plugins.

Current Scope

This first implementation slice focuses on the plugin architecture and the first target backends:

  • shared IR types in Rust
  • a plugin SDK that reads and writes IR over a serde boundary
  • a WASM runtime that executes plugins as WASI programs
  • a sample money plugin that rewrites decimal money fields to a domain type
  • a first Python backend that emits Pydantic models plus sync and async httpx clients
  • a first TypeScript backend that emits typed models plus a fetch-based client
  • a first Go backend that emits typed models plus a net/http client

The OpenAPI importer is in place, and the generator can now emit Python and TypeScript packages from openapi.json. Go is still to come.

Workspace Layout

  • crates/arvalez-ir: shared IR and validation
  • crates/arvalez-openapi: OpenAPI document loader and Core IR mapper
  • crates/arvalez-plugin-sdk: plugin-side protocol helpers
  • crates/arvalez-plugin-runtime: host-side WASM execution
  • crates/arvalez-target-python: Python SDK generator
  • crates/arvalez-target-typescript: TypeScript SDK generator
  • crates/arvalez-cli: local CLI for inspecting IR and running plugins
  • plugins/money-plugin: example WASM plugin

Build

Install the WASI target if needed:

rustup target add wasm32-wasip1

Build the example plugin:

cargo build -p money-plugin --target wasm32-wasip1

Run the plugin against the fixture IR:

cargo run -p arvalez-cli -- run-plugin --plugin money

Build Core IR from the local OpenAPI document:

cargo run -p arvalez-cli -- build-ir --openapi openapi.json

Run the plugin against a real OpenAPI document:

cargo run -p arvalez-cli -- run-plugin --plugin money --openapi openapi.json

Generate a Python SDK package:

cargo run -p arvalez-cli -- generate-python --openapi openapi.json --output-directory generated/python-client

Generate a TypeScript SDK package:

cargo run -p arvalez-cli -- generate-typescript --openapi openapi.json --output-directory generated/typescript-client

Generate a Go SDK package:

cargo run -p arvalez-cli -- generate-go --openapi openapi.json --output-directory generated/go-client

The generators also read optional settings from arvalez.toml:

[output]
directory = "generated"
group_by_tag = true
version = "1.0.0"

[output.go]
module_path = "github.com/acme/client"
package_name = "client"
version = "1.0.0"

[output.python]
package_name = "arvalez_client"
version = "1.0.1"
template_dir = "./templates/python"

[output.typescript]
package_name = "@arvalez/client"
version = "1.0.2"
template_dir = "./templates/typescript"

Override the configured output version from the CLI:

cargo run -p arvalez-cli -- generate-python --openapi openapi.json --output-directory generated/python-client --output-version 2.3.4

Generate all enabled backends into one output root:

cargo run -p arvalez-cli -- generate --openapi openapi.json --output-directory generated

Disable a backend from the CLI:

cargo run -p arvalez-cli -- generate --openapi openapi.json --output-directory generated --no-typescript

Disable a backend from config:

[output.typescript]
disabled = true
package_name = "@arvalez/client"

The Go backend also supports bundled default Tera templates with selective overrides:

cargo run -p arvalez-cli -- generate-go --openapi openapi.json --template-dir ./templates/go

Supported override names are:

  • package/go.mod.tera
  • package/README.md.tera
  • package/models.go.tera
  • package/client.go.tera
  • partials/model_struct.go.tera
  • partials/service.go.tera
  • partials/client_method.go.tera

When group_by_tag = true, tagged operations are grouped under subclients. For example, Python becomes client.ingredients.create_ingredient(...) and TypeScript becomes client.ingredients.createIngredient(...). Operations without tags stay on the root client, and multi-tag operations use the first tag.

Shared settings in [output] act as defaults, and [output.python] / [output.typescript] / [output.go] can override them per target. That includes group_by_tag, version, and similar cross-target options. CLI flags like --output-version override both.

Override only selected Python templates:

cargo run -p arvalez-cli -- generate-python --openapi openapi.json --template-dir ./templates/python

The Python backend ships with bundled default Tera templates inside the binary. Override files are optional and can be provided selectively. Supported override names are:

  • package/pyproject.toml.tera
  • package/README.md.tera
  • package/__init__.py.tera
  • package/models.py.tera
  • package/client.py.tera
  • partials/model_class.py.tera
  • partials/client_class.py.tera
  • partials/client_method.py.tera

Override only selected TypeScript templates:

cargo run -p arvalez-cli -- generate-typescript --openapi openapi.json --template-dir ./templates/typescript

The TypeScript backend also ships with bundled default Tera templates inside the binary. Supported override names are:

  • package/package.json.tera
  • package/tsconfig.json.tera
  • package/README.md.tera
  • package/models.ts.tera
  • package/client.ts.tera
  • package/index.ts.tera
  • partials/model_interface.ts.tera
  • partials/client_method.ts.tera
  • partials/tag_group.ts.tera

Inspect the raw fixture IR:

cargo run -p arvalez-cli -- inspect-ir

Docker

Build a container image with the precompiled CLI:

docker build -t arvalez .

Run the bundled tool against files mounted from the current workspace:

docker run --rm -v "$PWD:/work" -w /work arvalez build-ir --openapi openapi.json

Generate a Python SDK from inside the container:

docker run --rm -v "$PWD:/work" -w /work arvalez generate-python --openapi openapi.json --output-directory generated/python-client

Releases

Publishing a GitHub release triggers .github/workflows/release.yml, which:

  • checks that the release tag matches the workspace version in Cargo.toml
  • builds and pushes the multi-arch arvalez/cli image to Docker Hub
  • publishes the Rust crates to crates.io in dependency order

The workflow expects these GitHub repository secrets:

  • DOCKERHUB_USERNAME
  • DOCKERHUB_TOKEN
  • CARGO_REGISTRY_TOKEN

Set up pre-commit once after cloning:

pre-commit install

The pre-commit config keeps internal workspace dependency versions aligned with the workspace version and regenerates Cargo.lock whenever Cargo manifests are part of the commit.