Skip to content

Commit 31a496d

Browse files
authored
feat: Generate methods that use server-side streaming (#2474)
The generated methods look like this: ```dart /// Generates a [streamed response](https://ai.google.dev/gemini-api/docs/text-generation?lang=python#generate-a-text-stream) /// from the model given an input `GenerateContentRequest`. Stream<GenerateContentResponse> streamGenerateContent( GenerateContentRequest request, ) { final url = Uri.https(_host, '/v1/${request.model}:streamGenerateContent'); return _client .postStreaming(url, body: request) .map(GenerateContentResponse.fromJson); } ```
1 parent e0eeddb commit 31a496d

File tree

3 files changed

+39
-20
lines changed

3 files changed

+39
-20
lines changed

internal/sidekick/internal/dart/annotate.go

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,16 @@ func (m *messageAnnotation) HasToStringLines() bool {
111111
type methodAnnotation struct {
112112
Parent *api.Method
113113
// The method name using Dart naming conventions.
114-
Name string
115-
RequestMethod string
116-
RequestType string
117-
ResponseType string
118-
DocLines []string
119-
ReturnsValue bool
120-
BodyMessageName string
121-
QueryLines []string
122-
IsLROGetOperation bool
114+
Name string
115+
RequestMethod string
116+
RequestType string
117+
ResponseType string
118+
DocLines []string
119+
ReturnsValue bool
120+
BodyMessageName string
121+
QueryLines []string
122+
IsLROGetOperation bool
123+
ServerSideStreaming bool // Whether the server supports streaming via server-sent events (SSE).
123124
}
124125

125126
// HasBody returns true if the method has a body.
@@ -563,16 +564,17 @@ func (annotate *annotateModel) annotateMethod(method *api.Method) {
563564
}
564565

565566
annotation := &methodAnnotation{
566-
Parent: method,
567-
Name: strcase.ToLowerCamel(method.Name),
568-
RequestMethod: strings.ToLower(method.PathInfo.Bindings[0].Verb),
569-
RequestType: annotate.resolveTypeName(state.MessageByID[method.InputTypeID], true),
570-
ResponseType: annotate.resolveTypeName(state.MessageByID[method.OutputTypeID], true),
571-
DocLines: formatDocComments(method.Documentation, state),
572-
ReturnsValue: !method.ReturnsEmpty,
573-
BodyMessageName: bodyMessageName,
574-
QueryLines: queryLines,
575-
IsLROGetOperation: isGetOperation,
567+
Parent: method,
568+
Name: strcase.ToLowerCamel(method.Name),
569+
RequestMethod: strings.ToLower(method.PathInfo.Bindings[0].Verb),
570+
RequestType: annotate.resolveTypeName(state.MessageByID[method.InputTypeID], true),
571+
ResponseType: annotate.resolveTypeName(state.MessageByID[method.OutputTypeID], true),
572+
DocLines: formatDocComments(method.Documentation, state),
573+
ReturnsValue: !method.ReturnsEmpty,
574+
BodyMessageName: bodyMessageName,
575+
QueryLines: queryLines,
576+
IsLROGetOperation: isGetOperation,
577+
ServerSideStreaming: method.ServerSideStreaming,
576578
}
577579
method.Codec = annotation
578580
}

internal/sidekick/internal/dart/dart.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ func shouldGenerateMethod(m *api.Method) bool {
234234
// Ignore methods without HTTP annotations; we cannot generate working RPCs
235235
// for them.
236236
// TODO(#499) Switch to explicitly excluding such functions.
237-
if m.ClientSideStreaming || m.ServerSideStreaming || m.PathInfo == nil {
237+
if m.ClientSideStreaming || m.PathInfo == nil {
238238
return false
239239
}
240240
if len(m.PathInfo.Bindings) == 0 {

internal/sidekick/internal/dart/templates/lib/method.mustache

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@ limitations under the License.
1717
{{#Codec.DocLines}}
1818
{{{.}}}
1919
{{/Codec.DocLines}}
20+
{{#Codec.ServerSideStreaming}}
21+
Stream<{{Codec.ResponseType}}> {{Codec.Name}}({{Codec.RequestType}} request) {
22+
final url = Uri.https(_host, '{{PathInfo.Codec.PathFmt}}'
23+
{{#Codec.HasQueryLines}}, {
24+
{{#Codec.QueryLines}}
25+
{{{.}}},
26+
{{/Codec.QueryLines}}
27+
}
28+
{{/Codec.HasQueryLines}}
29+
);
30+
return _client
31+
.{{Codec.RequestMethod}}Streaming(url{{#Codec.HasBody}}, body: {{Codec.BodyMessageName}}{{/Codec.HasBody}})
32+
.map({{Codec.ResponseType}}.fromJson);
33+
}
34+
{{/Codec.ServerSideStreaming}}
35+
{{^Codec.ServerSideStreaming}}
2036
{{#Codec.IsLROGetOperation}}
2137
///
2238
/// This method can be used to get the current status of a long-running
@@ -51,3 +67,4 @@ Future<{{Codec.ResponseType}}{{#OperationInfo}}<{{Codec.ResponseType}}, {{Codec.
5167
{{/Codec.ReturnsValue}}
5268
}
5369
{{/Codec.IsLROGetOperation}}
70+
{{/Codec.ServerSideStreaming}}

0 commit comments

Comments
 (0)