Skip to content

Commit 6e38446

Browse files
authored
[Go] insert code snippets into flows.md (#469)
Create docs-go/flows.md by merging the text with snippets from a valid Go source file. This ensures that the examples in the docs at least compile.
1 parent 98c9ff5 commit 6e38446

File tree

6 files changed

+600
-69
lines changed

6 files changed

+600
-69
lines changed

docs-go/flows

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Flows
2+
3+
Flows are wrapped functions with some additional characteristics over direct
4+
calls: they are strongly typed, streamable, locally and remotely callable, and
5+
fully observable.
6+
Firebase Genkit provides CLI and developer UI tooling for running and debugging flows.
7+
8+
## Defining flows
9+
10+
In its simplest form, a flow just wraps a function:
11+
12+
- {Go}
13+
14+
%include ../go/internal/doc-snippets/flows.go flow1
15+
16+
Doing so lets you run the function from the Genkit CLI and developer UI, and is
17+
a requirement for many of Genkit's features, including deployment and
18+
observability.
19+
20+
An important advantage Genkit flows have over directly calling a model API is
21+
type safety of both inputs and outputs:
22+
23+
- {Go}
24+
25+
The argument and result types of a flow can be simple or structured values.
26+
Genkit will produce JSON schemas for these values using
27+
[`invopop/jsonschema`](https://pkg.go.dev/github.com/invopop/jsonschema).
28+
29+
The following flow takes a `string` as input and outputs a `struct`:
30+
31+
%include ../go/internal/doc-snippets/flows.go msug
32+
33+
%include ../go/internal/doc-snippets/flows.go flow2
34+
35+
## Running flows
36+
37+
To run a flow in your code:
38+
39+
- {Go}
40+
41+
%include ../go/internal/doc-snippets/flows.go run1
42+
43+
You can use the CLI to run flows as well:
44+
45+
```posix-terminal
46+
genkit flow:run menuSuggestionFlow '"French"'
47+
```
48+
49+
### Streamed
50+
51+
Here's a simple example of a flow that can stream values:
52+
53+
- {Go}
54+
55+
%include ../go/internal/doc-snippets/flows.go streaming-types
56+
57+
%include ../go/internal/doc-snippets/flows.go streaming
58+
59+
Note that the streaming callback can be undefined. It's only defined if the
60+
invoking client is requesting streamed response.
61+
62+
To invoke a flow in streaming mode:
63+
64+
- {Go}
65+
66+
%include ../go/internal/doc-snippets/flows.go invoke-streaming
67+
68+
If the flow doesn't implement streaming, `StreamFlow()` behaves identically to
69+
`RunFlow()`.
70+
71+
You can use the CLI to stream flows as well:
72+
73+
```posix-terminal
74+
genkit flow:run menuSuggestionFlow '"French"' -s
75+
```
76+
77+
## Deploying flows
78+
79+
If you want to be able to access your flow over HTTP you will need to deploy it
80+
first.
81+
82+
- {Go}
83+
84+
To deploy flows using Cloud Run and similar services, define your flows, and
85+
then call `StartFlowServer()`:
86+
87+
%include ../go/internal/doc-snippets/flows.go main
88+
89+
`StartFlowsServer` starts a `net/http` server that exposes your flows as HTTP
90+
endpoints (for example, `http://localhost:3400/menuSuggestionFlow`). Both
91+
parameters are optional:
92+
93+
- You can specify the address and port to listen on. If you don't,
94+
the server listens on any address and the port specified by the PORT
95+
environment variable; if that is empty, it uses the default of port 3400.
96+
- You can specify which flows to serve. If you don't, `StartFlowsServer`
97+
serves all of your defined flows.
98+
99+
If you want to serve flows on the same host and port as other endpoints, you
100+
can call `NewFlowServeMux()` to get a handler for your Genkit flows, which you
101+
can multiplex with your other route handlers:
102+
103+
%include ../go/internal/doc-snippets/flows.go mux
104+
105+
## Flow observability
106+
107+
Sometimes when using 3rd party SDKs that are not instrumented for observability,
108+
you might want to see them as a separate trace step in the Developer UI. All you
109+
need to do is wrap the code in the `run` function.
110+
111+
%include ../go/internal/doc-snippets/flows.go run

docs-go/flows.md

Lines changed: 74 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
<!-- Autogenerated by weave; DO NOT EDIT -->
2+
13
# Flows
24

35
Flows are wrapped functions with some additional characteristics over direct
@@ -13,12 +15,11 @@ In its simplest form, a flow just wraps a function:
1315

1416
```go
1517
menuSuggestionFlow := genkit.DefineFlow(
16-
"menuSuggestionFlow",
17-
func(ctx context.Context, restaurantTheme string) (string, error) {
18-
suggestion := makeMenuItemSuggestion(restaurantTheme)
19-
return suggestion, nil
20-
},
21-
)
18+
"menuSuggestionFlow",
19+
func(ctx context.Context, restaurantTheme string) (string, error) {
20+
suggestion := makeMenuItemSuggestion(restaurantTheme)
21+
return suggestion, nil
22+
})
2223
```
2324

2425
Doing so lets you run the function from the Genkit CLI and developer UI, and is
@@ -38,19 +39,19 @@ type safety of both inputs and outputs:
3839

3940
```go
4041
type MenuSuggestion struct {
41-
ItemName string `json:"item_name"`
42-
Description string `json:"description"`
43-
Calories int `json:"calories"`
42+
ItemName string `json:"item_name"`
43+
Description string `json:"description"`
44+
Calories int `json:"calories"`
4445
}
4546
```
4647

4748
```go
4849
menuSuggestionFlow := genkit.DefineFlow(
49-
"menuSuggestionFlow",
50-
func(ctx context.Context, restaurantTheme string) (MenuSuggestion, error) {
51-
suggestion := makeStructuredMenuItemSuggestion(restaurantTheme)
52-
return suggestion, nil
53-
},
50+
"menuSuggestionFlow",
51+
func(ctx context.Context, restaurantTheme string) (MenuSuggestion, error) {
52+
suggestion := makeStructuredMenuItemSuggestion(restaurantTheme)
53+
return suggestion, nil
54+
},
5455
)
5556
```
5657

@@ -78,32 +79,34 @@ Here's a simple example of a flow that can stream values:
7879

7980
```go
8081
// Types for illustrative purposes.
81-
type inputType string
82-
type outputType string
83-
type streamType string
82+
type InputType string
83+
type OutputType string
84+
type StreamType string
85+
```
8486

85-
menuSuggestionFlow := genkit.DefineFlow(
86-
"menuSuggestionFlow",
87-
func(
88-
ctx context.Context,
89-
restaurantTheme inputType,
90-
callback func(context.Context, streamType) error,
91-
) (outputType, error) {
92-
var menu strings.Builder
93-
menuChunks := make(chan streamType)
94-
go makeFullMenuSuggestion(restaurantTheme, menuChunks)
95-
for {
96-
chunk, ok := <-menuChunks
97-
if !ok {
98-
break
99-
}
100-
if callback != nil {
101-
callback(context.Background(), chunk)
102-
}
103-
menu.WriteString(string(chunk))
104-
}
105-
return outputType(menu.String()), nil
106-
},
87+
```go
88+
menuSuggestionFlow := genkit.DefineStreamingFlow(
89+
"menuSuggestionFlow",
90+
func(
91+
ctx context.Context,
92+
restaurantTheme InputType,
93+
callback func(context.Context, StreamType) error,
94+
) (OutputType, error) {
95+
var menu strings.Builder
96+
menuChunks := make(chan StreamType)
97+
go makeFullMenuSuggestion(restaurantTheme, menuChunks)
98+
for {
99+
chunk, ok := <-menuChunks
100+
if !ok {
101+
break
102+
}
103+
if callback != nil {
104+
callback(context.Background(), chunk)
105+
}
106+
menu.WriteString(string(chunk))
107+
}
108+
return OutputType(menu.String()), nil
109+
},
107110
)
108111
```
109112

@@ -116,16 +119,16 @@ To invoke a flow in streaming mode:
116119

117120
```go
118121
genkit.StreamFlow(
119-
context.Background(),
120-
menuSuggestionFlow,
121-
"French",
122-
)(func(sfv *genkit.StreamFlowValue[outputType, streamType], err error) bool {
123-
if !sfv.Done {
124-
fmt.Print(sfv.Output)
125-
return true
126-
} else {
127-
return false
128-
}
122+
context.Background(),
123+
menuSuggestionFlow,
124+
"French",
125+
)(func(sfv *genkit.StreamFlowValue[OutputType, StreamType], err error) bool {
126+
if !sfv.Done {
127+
fmt.Print(sfv.Output)
128+
return true
129+
} else {
130+
return false
131+
}
129132
})
130133
```
131134

@@ -150,16 +153,17 @@ first.
150153

151154
```go
152155
func main() {
153-
genkit.DefineFlow(
154-
"menuSuggestionFlow",
155-
func(ctx context.Context, restaurantTheme string) (string, error) {
156-
// ...
157-
},
158-
)
159-
err := genkit.StartFlowServer(":1234", []string{})
160-
161-
// startProdServer always returns a non-nil error: the one returned by
162-
// http.ListenAndServe.
156+
genkit.DefineFlow(
157+
"menuSuggestionFlow",
158+
func(ctx context.Context, restaurantTheme string) (string, error) {
159+
// ...
160+
return "", nil
161+
},
162+
)
163+
// StartFlowServer always returns a non-nil error: the one returned by
164+
// http.ListenAndServe.
165+
err := genkit.StartFlowServer(":1234", []string{})
166+
log.Fatal(err)
163167
}
164168
```
165169

@@ -179,7 +183,7 @@ first.
179183

180184
```go
181185
mainMux := http.NewServeMux()
182-
mainMux.Handle("POST /flow/", http.StripPrefix("/flow/", genkit.NewFlowServeMux()))
186+
mainMux.Handle("POST /flow/", http.StripPrefix("/flow/", genkit.NewFlowServeMux(nil)))
183187
```
184188

185189
## Flow observability
@@ -190,13 +194,14 @@ need to do is wrap the code in the `run` function.
190194

191195
```go
192196
genkit.DefineFlow(
193-
"menuSuggestionFlow",
194-
func(ctx context.Context, restaurantTheme string) (string, error) {
195-
themes, err := genkit.Run(ctx, "find-similar-themes", func() (string, error) {
196-
// ...
197-
})
198-
199-
// ...
200-
},
201-
)
197+
"menuSuggestionFlow",
198+
func(ctx context.Context, restaurantTheme string) (string, error) {
199+
themes, err := genkit.Run(ctx, "find-similar-themes", func() (string, error) {
200+
// ...
201+
return "", nil
202+
})
203+
204+
// ...
205+
return themes, err
206+
})
202207
```

docs-go/generate.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh -e
2+
3+
weave=$HOME/go/bin/weave
4+
if [[ ! -f $weave ]]; then
5+
echo "installing weave"
6+
go -C ../go install ./internal/cmd/weave
7+
fi
8+
9+
$weave flows > flows.md
10+
11+

0 commit comments

Comments
 (0)