Skip to content

Commit 6010efb

Browse files
authored
fix: improve openapi instructions for windows/java (#962)
1 parent c0480d5 commit 6010efb

File tree

4 files changed

+191
-25
lines changed

4 files changed

+191
-25
lines changed

docs/docs/get-started/quickstart/openapi.mdx

+152-11
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,18 @@ you can get a client library for free.
7070
</Tab>
7171

7272
<Tab title="Windows">
73-
To install `npx`, use the [Node.js installer](https://nodejs.org/en/download/prebuilt-installer).
73+
To install `npx` and `java`:
74+
75+
1. Use the [Node.js installer](https://nodejs.org/en/download/prebuilt-installer) to install `npx` (default installer settings are fine).
76+
2. Run `npm install -g npm@latest` to update `npx` (there is currently an [issue][npx-windows-issue] with the default install of `npx` on Windows where it doesn't work out of the box).
77+
3. Run the [Adoptium OpenJDK `.msi` installer](https://adoptium.net/temurin/releases/?os=windows) (install the JDK; default installer settings are fine).
7478

75-
To install `java`, use the [Adoptium OpenJDK `.msi` installer](https://adoptium.net/temurin/releases/?os=windows).
79+
You can verify that `npx` and `java` are installed by running:
80+
81+
```powershell
82+
npx -version
83+
java -version
84+
```
7685
</Tab>
7786

7887
<Tab title="Other">
@@ -89,10 +98,17 @@ you can get a client library for free.
8998
on your needs, we can also provide a static binary for using BAML.
9099
</Note>
91100

92-
101+
[npx-windows-issue]: https://github.com/nodejs/node/issues/53538
102+
93103
### Create a new BAML project
94104

95-
This will give you some starter BAML code in a `baml_src` directory.
105+
This will give you some starter BAML code in a `baml_src` directory, and also
106+
set up `generator.baml` based on `--openapi-client-type`, so that BAML will:
107+
108+
- compile your BAML functions into an OpenAPI specification, and
109+
- configure `on_generate` to generate an OpenAPI client in the language of your choosing
110+
111+
<p></p>
96112

97113
<Tabs>
98114

@@ -122,10 +138,23 @@ you can get a client library for free.
122138
</Tab>
123139

124140
<Tab title="Java">
141+
125142
```bash
126143
npx @boundaryml/baml init \
127144
--client-type rest/openapi --openapi-client-type java
128145
```
146+
147+
Notice that `on_generate` has been initialized for you to:
148+
149+
- run the OpenAPI generator to generate a Java client library, and _also_
150+
- run `mvn clean install` to install the generated client library to your
151+
local Maven repository
152+
153+
<Warning>
154+
If you only use Maven through an IDE (e.g. IntelliJ IDEA), you should
155+
remove `&& mvn clean install` from the generated `on_generate` command.
156+
</Warning>
157+
129158
</Tab>
130159

131160
<Tab title="PHP">
@@ -135,6 +164,13 @@ you can get a client library for free.
135164
```
136165
</Tab>
137166

167+
<Tab title="Ruby">
168+
```bash
169+
npx @boundaryml/baml init \
170+
--client-type rest/openapi --openapi-client-type ruby
171+
```
172+
</Tab>
173+
138174
<Tab title="Rust">
139175
```bash
140176
npx @boundaryml/baml init \
@@ -225,17 +261,114 @@ func main() {
225261
</Tab>
226262

227263
<Tab title="Java">
228-
<Warning>
229-
The README that the Java OpenAPI generator generates will have one mistake: it
230-
will suggest importing from `baml_client.models.*`, but the correct
231-
package to import from is `baml_client.model.*`. The OpenAPI team
232-
will [fix this
233-
soon](https://github.com/OpenAPITools/openapi-generator/issues/19431).
234-
</Warning>
264+
First, add the OpenAPI-generated client to your project.
265+
266+
<AccordionGroup>
267+
268+
<Accordion title="If you have 'mvn' in your PATH">
269+
270+
You can use the default `on_generate` command, which will tell `baml dev` to
271+
install the OpenAPI-generated client into your local Maven repository by running
272+
`mvn clean install` every time you save a change to a BAML file.
273+
274+
To depend on the client in your local Maven repo, you can use these configs:
275+
276+
<CodeGroup>
277+
```xml pom.xml
278+
<dependency>
279+
<groupId>org.openapitools</groupId>
280+
<artifactId>openapi-java-client</artifactId>
281+
<version>0.1.0</version>
282+
<scope>compile</scope>
283+
</dependency>
284+
```
285+
286+
```kotlin settings.gradle.kts
287+
repositories {
288+
mavenCentral()
289+
mavenLocal()
290+
}
291+
292+
dependencies {
293+
implementation("org.openapitools:openapi-java-client:0.1.0")
294+
}
295+
```
296+
</CodeGroup>
297+
298+
</Accordion>
299+
300+
<Accordion title="If you don't have 'mvn' in your PATH">
301+
302+
You'll probably want to comment out `on_generate` and instead use either the [OpenAPI Maven plugin] or [OpenAPI Gradle plugin] to build your OpenAPI client.
303+
304+
[OpenAPI Maven plugin]: https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-maven-plugin
305+
[OpenAPI Gradle plugin]: https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-gradle-plugin
306+
307+
<CodeGroup>
308+
```xml pom.xml
309+
<build>
310+
<plugins>
311+
<plugin>
312+
<groupId>org.openapitools</groupId>
313+
<artifactId>openapi-generator-maven-plugin</artifactId>
314+
<version>7.8.0</version> <!-- Use the latest stable version -->
315+
<executions>
316+
<execution>
317+
<goals>
318+
<goal>generate</goal>
319+
</goals>
320+
<configuration>
321+
<inputSpec>${project.basedir}/baml_client/openapi.yaml</inputSpec>
322+
<generatorName>baml</generatorName> <!-- or another generator name, e.g. 'kotlin' or 'spring' -->
323+
<output>${project.build.directory}/generated-sources/openapi</output>
324+
<apiPackage>com.boundaryml.baml_client.api</apiPackage>
325+
<modelPackage>com.boundaryml.baml_client.model</modelPackage>
326+
<invokerPackage>com.boundaryml.baml_client</invokerPackage>
327+
<java8>true</java8>
328+
</configuration>
329+
</execution>
330+
</executions>
331+
</plugin>
332+
</plugins>
333+
</build>
334+
```
335+
336+
```kotlin settings.gradle.kts
337+
plugins {
338+
id("org.openapi.generator") version "7.8.0"
339+
}
340+
341+
openApiGenerate {
342+
generatorName.set("java") // Change to 'kotlin', 'spring', etc. if needed
343+
inputSpec.set("${projectDir}/baml_client/openapi.yaml")
344+
outputDir.set("$buildDir/generated-sources/openapi")
345+
apiPackage.set("com.boundaryml.baml_client.api")
346+
modelPackage.set("com.boundaryml.baml_client.model")
347+
invokerPackage.set("com.boundaryml.baml_client")
348+
additionalProperties.set(mapOf("java8" to "true"))
349+
}
350+
351+
sourceSets["main"].java {
352+
srcDir("$buildDir/generated-sources/openapi/src/main/java")
353+
}
354+
355+
tasks.named("compileJava") {
356+
dependsOn("openApiGenerate")
357+
}
358+
```
359+
</CodeGroup>
360+
361+
</Accordion>
362+
</AccordionGroup>
363+
364+
Then, copy this code into wherever your `main` function is:
365+
235366
```Java
236367
import com.boundaryml.baml_client.ApiClient;
237368
import com.boundaryml.baml_client.ApiException;
238369
import com.boundaryml.baml_client.Configuration;
370+
// NOTE: baml_client/README.md will suggest importing from models.* - that is wrong.
371+
// See https://github.com/OpenAPITools/openapi-generator/issues/19431 for more details.
239372
import com.boundaryml.baml_client.model.*;
240373
import com.boundaryml.baml_client.api.DefaultApi;
241374

@@ -268,6 +401,8 @@ public class Example {
268401
you, and you need help working around it.
269402
</Warning>
270403

404+
First, add the OpenAPI-generated client to your project:
405+
271406
```json composer.json
272407
"repositories": [
273408
{
@@ -280,6 +415,8 @@ public class Example {
280415
}
281416
```
282417

418+
You can now use this code to call a BAML function:
419+
283420
```PHP
284421
<?php
285422
require_once(__DIR__ . '/vendor/autoload.php');
@@ -350,11 +487,15 @@ end
350487
```
351488
</Tip>
352489

490+
First, add the OpenAPI-generated client to your project:
491+
353492
```toml Cargo.toml
354493
[dependencies]
355494
baml-client = { path = "./baml_client" }
356495
```
357496

497+
You can now use `cargo run`:
498+
358499
```rust
359500
use baml_client::models::ExtractResumeRequest;
360501
use baml_client::apis::default_api as b;

engine/Cargo.lock

+28
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

engine/baml-runtime/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ reqwest = { version = "0.12.5", features = [
123123
"stream",
124124
] }
125125
walkdir = "2.5.0"
126+
which = "6.0.3"
126127

127128
[features]
128129
defaults = []

engine/baml-runtime/src/cli/init.rs

+10-14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{path::PathBuf, process::Command};
33
use anyhow::Result;
44
use baml_types::GeneratorOutputType;
55
use include_dir::include_dir;
6+
use which::which;
67

78
#[derive(clap::Args, Debug)]
89
pub struct InitArgs {
@@ -29,23 +30,15 @@ static SAMPLE_PROJECT: include_dir::Dir =
2930

3031
/// TODO: one problem with this impl - this requires all users to install openapi-generator the same way
3132
fn infer_openapi_command() -> Result<&'static str> {
32-
if Command::new("which")
33-
.args(["openapi-generator"])
34-
.output()
35-
.is_ok_and(|output| output.status.success())
36-
{
33+
if which("openapi-generator").is_ok() {
3734
return Ok("openapi-generator");
3835
}
3936

40-
if Command::new("which")
41-
.args(["openapi-generator-cli"])
42-
.output()
43-
.is_ok_and(|output| output.status.success())
44-
{
37+
if which("openapi-generator-cli").is_ok() {
4538
return Ok("openapi-generator-cli");
4639
}
4740

48-
if Command::new("npx").args(["--version"]).status().is_ok() {
41+
if which("npx").is_ok() {
4942
return Ok("npx @openapitools/openapi-generator-cli");
5043
}
5144

@@ -74,7 +67,10 @@ impl InitArgs {
7467
let openapi_generator_path = infer_openapi_command();
7568

7669
if let Err(e) = &openapi_generator_path {
77-
log::warn!("OpenAPI client generator will be skipped, since we failed to find one in your PATH: {}", e);
70+
log::warn!(
71+
"Failed to find openapi-generator-cli in your PATH, defaulting to using npx: {}",
72+
e
73+
);
7874
}
7975

8076
let main_baml_content = generate_main_baml_content(
@@ -140,7 +136,7 @@ fn generate_main_baml_content(
140136
"{cmd} --additional-properties enumClassPrefix=true,isGoSubmodule=true,packageName=baml_client,withGoMod=false",
141137
),
142138
Some("java") => format!(
143-
"{cmd} --additional-properties invokerPackage=com.boundaryml.baml_client,modelPackage=com.boundaryml.baml_client.model,apiPackage=com.boundaryml.baml_client.api,java8=true && cd ../baml_client && mvn clean install",
139+
"{cmd} --additional-properties invokerPackage=com.boundaryml.baml_client,modelPackage=com.boundaryml.baml_client.model,apiPackage=com.boundaryml.baml_client.api,java8=true && mvn clean install",
144140
),
145141
Some("php") => format!(
146142
"{cmd} --additional-properties composerPackageName=boundaryml/baml-client,invokerPackage=BamlClient",
@@ -349,7 +345,7 @@ generator target {{
349345
350346
// 'baml-cli generate' will run this after generating openapi.yaml, to generate your OpenAPI client
351347
// This command will be run from within $output_dir
352-
on_generate "openapi-generator generate -i openapi.yaml -g java -o . --additional-properties invokerPackage=com.boundaryml.baml_client,modelPackage=com.boundaryml.baml_client.model,apiPackage=com.boundaryml.baml_client.api,java8=true && cd ../baml_client && mvn clean install"
348+
on_generate "openapi-generator generate -i openapi.yaml -g java -o . --additional-properties invokerPackage=com.boundaryml.baml_client,modelPackage=com.boundaryml.baml_client.model,apiPackage=com.boundaryml.baml_client.api,java8=true && mvn clean install"
353349
}}
354350
"#,
355351
env!("CARGO_PKG_VERSION")

0 commit comments

Comments
 (0)