Skip to content

Commit

Permalink
some last changes to init
Browse files Browse the repository at this point in the history
  • Loading branch information
sxlijin committed Sep 5, 2024
1 parent 81937e3 commit ce39e00
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 74 deletions.
10 changes: 10 additions & 0 deletions docs/docs/get-started/quickstart/openapi.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,16 @@ try {
</Tab>

<Tab title="Rust">

<Tip>
If you're using `cargo watch -- cargo build` and seeing build failures because it can't find
the generated `baml_client`, try increasing the delay on `cargo watch` to 1 second like so:

```bash
cargo watch --delay 1 -- cargo build
```
</Tip>

```toml Cargo.toml
[dependencies]
baml-client = { path = "./baml_client" }
Expand Down
10 changes: 9 additions & 1 deletion engine/baml-runtime/src/cli/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ fn generate_main_baml_content(
);

let openapi_generate_command = match openapi_client_type {
Some("go") => format!(
"{} --additional-properties enumClassPrefix=true,isGoSubmodule=true,packageName=baml_client,withGoMod=false",
openapi_generate_command
),
Some("java") => format!(
"{} --additional-properties generateApiTests=false,generateModelTests=false && cd ../baml_client && mvn clean install",
openapi_generate_command
Expand All @@ -145,6 +149,10 @@ fn generate_main_baml_content(
"{} --additional-properties composerPackageName=boundaryml/baml-client",
openapi_generate_command
),
Some("ruby") => format!(
"{} --additional-properties gemName=baml_client",
openapi_generate_command
),
Some("rust") => format!(
"{} --additional-properties packageName=baml-client",
openapi_generate_command
Expand All @@ -171,7 +179,7 @@ fn generate_main_baml_content(
// 'baml-cli generate' will run this after generating openapi.yaml, to generate your OpenAPI client
// This command will be run from within $output_dir
{}"#,
openapi_generate_command
openapi_generate_command.trim_start()
);

vec![
Expand Down
91 changes: 70 additions & 21 deletions engine/language_client_codegen/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,46 @@ impl Serialize for OpenApiSchema<'_> {
&self,
serializer: S,
) -> core::result::Result<S::Ok, S::Error> {
let baml_image_schema = TypeSpecWithMeta {
meta: TypeMetadata {
title: Some("BamlImage".to_string()),
r#enum: None,
r#const: None,
nullable: false,
},
type_spec: TypeSpec::Inline(TypeDef::Class {
properties: vec![
(
"base64".to_string(),
TypeSpecWithMeta {
meta: TypeMetadata {
title: None,
r#enum: None,
r#const: None,
nullable: false,
},
type_spec: TypeSpec::Inline(TypeDef::String),
},
),
(
"media_type".to_string(),
TypeSpecWithMeta {
meta: TypeMetadata {
title: None,
r#enum: None,
r#const: None,
nullable: true,
},
type_spec: TypeSpec::Inline(TypeDef::String),
},
),
]
.into_iter()
.collect(),
required: vec!["base64".to_string()],
additional_properties: false,
}),
};
let schemas = match self
.schemas
.iter()
Expand Down Expand Up @@ -106,7 +146,7 @@ impl Serialize for OpenApiSchema<'_> {
])
.collect::<IndexMap<_, _>>(),
"components": {
"requestBodies": self.paths.iter().map(|(p)| {
"requestBodies": self.paths.iter().map(|p| {
(p.function_name, json!({
"required": true,
"content": {
Expand All @@ -130,9 +170,9 @@ impl Serialize for OpenApiSchema<'_> {
},
"media_type": {
"type": "string",
"nullable": true,
},
}
},
"required": ["base64"],
},
{
"type": "object",
Expand All @@ -143,9 +183,9 @@ impl Serialize for OpenApiSchema<'_> {
},
"media_type": {
"type": "string",
"nullable": true,
},
}
},
"required": ["url"],
}
],
}),
Expand All @@ -163,9 +203,9 @@ impl Serialize for OpenApiSchema<'_> {
},
"media_type": {
"type": "string",
"nullable": true,
},
}
},
"required": ["base64"],
},
{
"type": "object",
Expand All @@ -176,9 +216,9 @@ impl Serialize for OpenApiSchema<'_> {
},
"media_type": {
"type": "string",
"nullable": true,
},
}
},
"required": ["url"],
}
],
}),
Expand Down Expand Up @@ -293,8 +333,16 @@ impl<'ir> TryFrom<Walker<'ir, &'ir Node<Function>>> for OpenApiMethodDef<'ir> {
function_name,
request_body: TypeSpecWithMeta {
meta: TypeMetadata {
// title: Some(format!("{}Request", function_name)),
title: None,
// We _deliberately_ set this, even though OpenAPI doesn't require it,
// because some generators will de-duplicate names of generated types
// based on type shape
//
// For example, the Golang generator will use "ClassifyMessageRequest" as the
// request type for b.GetOrderInfo if they both have (input: string) as their
// function arg signature (I think the Java generator too?)
//
// title: None,
title: Some(format!("{}Request", function_name)),
r#enum: None,
r#const: None,
nullable: false,
Expand Down Expand Up @@ -468,7 +516,9 @@ impl<'ir> ToTypeReferenceInTypeDefinition<'ir> for FieldType {
TypeValue::Float => TypeSpec::Inline(TypeDef::Float),
// TODO: should this support "format: int64"?
TypeValue::Int => TypeSpec::Inline(TypeDef::Int),
TypeValue::Null => anyhow::bail!("OpenAPI does not support null literals"),
TypeValue::Null => anyhow::bail!(
"BAML<->OpenAPI only allows nulls in unions, not as a literal"
),
TypeValue::String => TypeSpec::Inline(TypeDef::String),
TypeValue::Media(BamlMediaType::Audio) => TypeSpec::Ref {
r#ref: format!("#/components/schemas/BamlAudio"),
Expand All @@ -479,25 +529,24 @@ impl<'ir> ToTypeReferenceInTypeDefinition<'ir> for FieldType {
},
},
FieldType::Union(inner) => {
let (null_types, nonnull_types): (Vec<_>, Vec<_>) =
let (_nulls, nonnull_types): (Vec<_>, Vec<_>) =
inner.into_iter().partition(|t| t.is_null());

// dbg!(&null_types);

let one_of = nonnull_types
.iter()
.map(|t| t.to_type_spec(ir))
.collect::<Result<_>>()?;
.collect::<Result<Vec<_>>>()?;
if one_of.is_empty() {
anyhow::bail!("BAML<->OpenAPI unions must have at least one non-null type")
}
TypeSpecWithMeta {
meta: TypeMetadata {
title: None,
r#enum: None,
r#const: None,
nullable: if nonnull_types.is_empty() {
false
} else {
true
},
nullable: false,
},
type_spec: TypeSpec::Union { one_of },
}
Expand All @@ -507,8 +556,8 @@ impl<'ir> ToTypeReferenceInTypeDefinition<'ir> for FieldType {
}
FieldType::Optional(inner) => {
let mut type_spec = inner.to_type_spec(ir)?;
type_spec.meta.nullable = true;
// TODO: if type_spec is of an enum, add "null" to the list of values
// TODO: if type_spec is of an enum, consider adding "null" to the list of values
// something i saw suggested doing this
type_spec
}
})
Expand Down
Loading

0 comments on commit ce39e00

Please sign in to comment.