Skip to content

Commit dc72c81

Browse files
feat(api): add since parameter to deployment logs endpoint
1 parent a62b964 commit dc72c81

10 files changed

Lines changed: 94 additions & 13 deletions

File tree

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 16
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-b019e469425a59061f37c5fdc7a131a5291c66134ef0627db4f06bb1f4af0b15.yml
3-
openapi_spec_hash: f66a3c2efddb168db9539ba2507b10b8
4-
config_hash: aae6721b2be9ec8565dfc8f7eadfe105
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-2aec229ccf91f7c1ac95aa675ea2a59bd61af9e363a22c3b49677992f1eeb16a.yml
3+
openapi_spec_hash: c80cd5d52a79cd5366a76d4a825bd27a
4+
config_hash: b8e1fff080fbaa22656ab0a57b591777

aliases.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ type ErrorEvent = shared.ErrorEvent
2727
// This is an alias to an internal type.
2828
type ErrorModel = shared.ErrorModel
2929

30+
// Heartbeat event sent periodically to keep SSE connection alive.
31+
//
32+
// This is an alias to an internal type.
33+
type HeartbeatEvent = shared.HeartbeatEvent
34+
3035
// A log entry from the application.
3136
//
3237
// This is an alias to an internal type.

api.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared">shared</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared#ErrorDetail">ErrorDetail</a>
44
- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared">shared</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared#ErrorEvent">ErrorEvent</a>
55
- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared">shared</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared#ErrorModel">ErrorModel</a>
6+
- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared">shared</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared#HeartbeatEvent">HeartbeatEvent</a>
67
- <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared">shared</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk/shared#LogEvent">LogEvent</a>
78

89
# Deployments
@@ -18,7 +19,7 @@ Methods:
1819

1920
- <code title="post /deployments">client.Deployments.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentService.New">New</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, body <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentNewParams">DeploymentNewParams</a>) (<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentNewResponse">DeploymentNewResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
2021
- <code title="get /deployments/{id}">client.Deployments.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentService.Get">Get</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentGetResponse">DeploymentGetResponse</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
21-
- <code title="get /deployments/{id}/events">client.Deployments.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentService.Follow">Follow</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) (<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentFollowResponseUnion">DeploymentFollowResponseUnion</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
22+
- <code title="get /deployments/{id}/events">client.Deployments.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentService.Follow">Follow</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, query <a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentFollowParams">DeploymentFollowParams</a>) (<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/onkernel/kernel-go-sdk#DeploymentFollowResponseUnion">DeploymentFollowResponseUnion</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
2223

2324
# Apps
2425

app.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ type AppListResponse struct {
5151
ID string `json:"id,required"`
5252
// Name of the application
5353
AppName string `json:"app_name,required"`
54+
// Deployment ID
55+
Deployment string `json:"deployment,required"`
5456
// Deployment region code
5557
Region constant.AwsUsEast1a `json:"region,required"`
5658
// Version label for the application
@@ -61,6 +63,7 @@ type AppListResponse struct {
6163
JSON struct {
6264
ID respjson.Field
6365
AppName respjson.Field
66+
Deployment respjson.Field
6467
Region respjson.Field
6568
Version respjson.Field
6669
EnvVars respjson.Field

appdeployment.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,15 @@ const (
147147

148148
// AppDeploymentFollowResponseUnion contains all possible properties and values
149149
// from [AppDeploymentFollowResponseState],
150-
// [AppDeploymentFollowResponseStateUpdate], [shared.LogEvent].
150+
// [AppDeploymentFollowResponseStateUpdate], [shared.LogEvent],
151+
// [shared.HeartbeatEvent].
151152
//
152153
// Use the [AppDeploymentFollowResponseUnion.AsAny] method to switch on the
153154
// variant.
154155
//
155156
// Use the methods beginning with 'As' to cast the union to one of its variants.
156157
type AppDeploymentFollowResponseUnion struct {
157-
// Any of "state", "state_update", "log".
158+
// Any of "state", "state_update", "log", "sse_heartbeat".
158159
Event string `json:"event"`
159160
State string `json:"state"`
160161
Timestamp time.Time `json:"timestamp"`
@@ -185,6 +186,7 @@ func (AppDeploymentFollowResponseStateUpdate) ImplAppDeploymentFollowResponseUni
185186
// case kernel.AppDeploymentFollowResponseState:
186187
// case kernel.AppDeploymentFollowResponseStateUpdate:
187188
// case shared.LogEvent:
189+
// case shared.HeartbeatEvent:
188190
// default:
189191
// fmt.Errorf("no variant present")
190192
// }
@@ -196,6 +198,8 @@ func (u AppDeploymentFollowResponseUnion) AsAny() anyAppDeploymentFollowResponse
196198
return u.AsStateUpdate()
197199
case "log":
198200
return u.AsLog()
201+
case "sse_heartbeat":
202+
return u.AsSseHeartbeat()
199203
}
200204
return nil
201205
}
@@ -215,6 +219,11 @@ func (u AppDeploymentFollowResponseUnion) AsLog() (v shared.LogEvent) {
215219
return
216220
}
217221

222+
func (u AppDeploymentFollowResponseUnion) AsSseHeartbeat() (v shared.HeartbeatEvent) {
223+
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
224+
return
225+
}
226+
218227
// Returns the unmodified JSON received from the API
219228
func (u AppDeploymentFollowResponseUnion) RawJSON() string { return u.JSON.raw }
220229

client_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,11 @@ func TestContextDeadlineStreaming(t *testing.T) {
311311
},
312312
}),
313313
)
314-
stream := client.Deployments.FollowStreaming(deadlineCtx, "id")
314+
stream := client.Deployments.FollowStreaming(
315+
deadlineCtx,
316+
"id",
317+
kernel.DeploymentFollowParams{},
318+
)
315319
for stream.Next() {
316320
_ = stream.Current()
317321
}
@@ -359,6 +363,7 @@ func TestContextDeadlineStreamingWithRequestTimeout(t *testing.T) {
359363
stream := client.Deployments.FollowStreaming(
360364
context.Background(),
361365
"id",
366+
kernel.DeploymentFollowParams{},
362367
option.WithRequestTimeout((100 * time.Millisecond)),
363368
)
364369
for stream.Next() {

deployment.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ import (
1111
"io"
1212
"mime/multipart"
1313
"net/http"
14+
"net/url"
1415
"time"
1516

1617
"github.com/onkernel/kernel-go-sdk/internal/apiform"
1718
"github.com/onkernel/kernel-go-sdk/internal/apijson"
19+
"github.com/onkernel/kernel-go-sdk/internal/apiquery"
1820
"github.com/onkernel/kernel-go-sdk/internal/requestconfig"
1921
"github.com/onkernel/kernel-go-sdk/option"
2022
"github.com/onkernel/kernel-go-sdk/packages/param"
@@ -66,7 +68,7 @@ func (r *DeploymentService) Get(ctx context.Context, id string, opts ...option.R
6668
// Establishes a Server-Sent Events (SSE) stream that delivers real-time logs and
6769
// status updates for a deployment. The stream terminates automatically once the
6870
// deployment reaches a terminal state.
69-
func (r *DeploymentService) FollowStreaming(ctx context.Context, id string, opts ...option.RequestOption) (stream *ssestream.Stream[DeploymentFollowResponseUnion]) {
71+
func (r *DeploymentService) FollowStreaming(ctx context.Context, id string, query DeploymentFollowParams, opts ...option.RequestOption) (stream *ssestream.Stream[DeploymentFollowResponseUnion]) {
7072
var (
7173
raw *http.Response
7274
err error
@@ -78,7 +80,7 @@ func (r *DeploymentService) FollowStreaming(ctx context.Context, id string, opts
7880
return
7981
}
8082
path := fmt.Sprintf("deployments/%s/events", id)
81-
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &raw, opts...)
83+
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &raw, opts...)
8284
return ssestream.NewStream[DeploymentFollowResponseUnion](ssestream.NewDecoder(raw), err)
8385
}
8486

@@ -253,13 +255,14 @@ const (
253255

254256
// DeploymentFollowResponseUnion contains all possible properties and values from
255257
// [shared.LogEvent], [DeploymentStateEvent],
256-
// [DeploymentFollowResponseAppVersionSummaryEvent], [shared.ErrorEvent].
258+
// [DeploymentFollowResponseAppVersionSummaryEvent], [shared.ErrorEvent],
259+
// [shared.HeartbeatEvent].
257260
//
258261
// Use the [DeploymentFollowResponseUnion.AsAny] method to switch on the variant.
259262
//
260263
// Use the methods beginning with 'As' to cast the union to one of its variants.
261264
type DeploymentFollowResponseUnion struct {
262-
// Any of "log", "deployment_state", nil, nil.
265+
// Any of "log", "deployment_state", nil, nil, "sse_heartbeat".
263266
Event string `json:"event"`
264267
// This field is from variant [shared.LogEvent].
265268
Message string `json:"message"`
@@ -316,6 +319,11 @@ func (u DeploymentFollowResponseUnion) AsErrorEvent() (v shared.ErrorEvent) {
316319
return
317320
}
318321

322+
func (u DeploymentFollowResponseUnion) AsSseHeartbeat() (v shared.HeartbeatEvent) {
323+
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
324+
return
325+
}
326+
319327
// Returns the unmodified JSON received from the API
320328
func (u DeploymentFollowResponseUnion) RawJSON() string { return u.JSON.raw }
321329

@@ -423,3 +431,17 @@ type DeploymentNewParamsRegion string
423431
const (
424432
DeploymentNewParamsRegionAwsUsEast1a DeploymentNewParamsRegion = "aws.us-east-1a"
425433
)
434+
435+
type DeploymentFollowParams struct {
436+
// Show logs since the given time (RFC timestamps or durations like 5m).
437+
Since param.Opt[string] `query:"since,omitzero" json:"-"`
438+
paramObj
439+
}
440+
441+
// URLQuery serializes [DeploymentFollowParams]'s query parameters as `url.Values`.
442+
func (r DeploymentFollowParams) URLQuery() (v url.Values, err error) {
443+
return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{
444+
ArrayFormat: apiquery.ArrayQueryFormatComma,
445+
NestedFormat: apiquery.NestedQueryFormatBrackets,
446+
})
447+
}

invocation.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,13 +321,14 @@ const (
321321
)
322322

323323
// InvocationFollowResponseUnion contains all possible properties and values from
324-
// [shared.LogEvent], [InvocationStateEvent], [shared.ErrorEvent].
324+
// [shared.LogEvent], [InvocationStateEvent], [shared.ErrorEvent],
325+
// [shared.HeartbeatEvent].
325326
//
326327
// Use the [InvocationFollowResponseUnion.AsAny] method to switch on the variant.
327328
//
328329
// Use the methods beginning with 'As' to cast the union to one of its variants.
329330
type InvocationFollowResponseUnion struct {
330-
// Any of "log", "invocation_state", "error".
331+
// Any of "log", "invocation_state", "error", "sse_heartbeat".
331332
Event string `json:"event"`
332333
// This field is from variant [shared.LogEvent].
333334
Message string `json:"message"`
@@ -361,6 +362,7 @@ func (InvocationStateEvent) ImplInvocationFollowResponseUnion() {}
361362
// case shared.LogEvent:
362363
// case kernel.InvocationStateEvent:
363364
// case shared.ErrorEvent:
365+
// case shared.HeartbeatEvent:
364366
// default:
365367
// fmt.Errorf("no variant present")
366368
// }
@@ -372,6 +374,8 @@ func (u InvocationFollowResponseUnion) AsAny() anyInvocationFollowResponse {
372374
return u.AsInvocationState()
373375
case "error":
374376
return u.AsError()
377+
case "sse_heartbeat":
378+
return u.AsSseHeartbeat()
375379
}
376380
return nil
377381
}
@@ -391,6 +395,11 @@ func (u InvocationFollowResponseUnion) AsError() (v shared.ErrorEvent) {
391395
return
392396
}
393397

398+
func (u InvocationFollowResponseUnion) AsSseHeartbeat() (v shared.HeartbeatEvent) {
399+
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
400+
return
401+
}
402+
394403
// Returns the unmodified JSON received from the API
395404
func (u InvocationFollowResponseUnion) RawJSON() string { return u.JSON.raw }
396405

shared/constant/constants.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type DeploymentState string // Always "deployment_state"
2424
type Error string // Always "error"
2525
type InvocationState string // Always "invocation_state"
2626
type Log string // Always "log"
27+
type SseHeartbeat string // Always "sse_heartbeat"
2728
type State string // Always "state"
2829
type StateUpdate string // Always "state_update"
2930

@@ -33,6 +34,7 @@ func (c DeploymentState) Default() DeploymentState { return "deployment_stat
3334
func (c Error) Default() Error { return "error" }
3435
func (c InvocationState) Default() InvocationState { return "invocation_state" }
3536
func (c Log) Default() Log { return "log" }
37+
func (c SseHeartbeat) Default() SseHeartbeat { return "sse_heartbeat" }
3638
func (c State) Default() State { return "state" }
3739
func (c StateUpdate) Default() StateUpdate { return "state_update" }
3840

@@ -42,6 +44,7 @@ func (c DeploymentState) MarshalJSON() ([]byte, error) { return marshalString(
4244
func (c Error) MarshalJSON() ([]byte, error) { return marshalString(c) }
4345
func (c InvocationState) MarshalJSON() ([]byte, error) { return marshalString(c) }
4446
func (c Log) MarshalJSON() ([]byte, error) { return marshalString(c) }
47+
func (c SseHeartbeat) MarshalJSON() ([]byte, error) { return marshalString(c) }
4548
func (c State) MarshalJSON() ([]byte, error) { return marshalString(c) }
4649
func (c StateUpdate) MarshalJSON() ([]byte, error) { return marshalString(c) }
4750

shared/shared.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,30 @@ func (r *ErrorModel) UnmarshalJSON(data []byte) error {
8787
return apijson.UnmarshalRoot(data, r)
8888
}
8989

90+
// Heartbeat event sent periodically to keep SSE connection alive.
91+
type HeartbeatEvent struct {
92+
// Event type identifier (always "sse_heartbeat").
93+
Event constant.SseHeartbeat `json:"event,required"`
94+
// Time the heartbeat was sent.
95+
Timestamp time.Time `json:"timestamp,required" format:"date-time"`
96+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
97+
JSON struct {
98+
Event respjson.Field
99+
Timestamp respjson.Field
100+
ExtraFields map[string]respjson.Field
101+
raw string
102+
} `json:"-"`
103+
}
104+
105+
// Returns the unmodified JSON received from the API
106+
func (r HeartbeatEvent) RawJSON() string { return r.JSON.raw }
107+
func (r *HeartbeatEvent) UnmarshalJSON(data []byte) error {
108+
return apijson.UnmarshalRoot(data, r)
109+
}
110+
111+
func (HeartbeatEvent) ImplAppDeploymentFollowResponseUnion() {}
112+
func (HeartbeatEvent) ImplInvocationFollowResponseUnion() {}
113+
90114
// A log entry from the application.
91115
type LogEvent struct {
92116
// Event type identifier (always "log").

0 commit comments

Comments
 (0)