The Nebius SDK for Go is a comprehensive client library for interacting with nebius.ai services. Built on gRPC, it supports all APIs defined in the Nebius API repository. This SDK simplifies resource management, authentication, and communication with Nebius services, making it a valuable tool for developers.
Add the SDK to your Go project with the following command:
go get github.com/nebius/gosdk
To update to the latest version:
go get -u github.com/nebius/gosdk
- Minimum Supported Version: Go 1.22
- The SDK is regularly tested against the latest Go release.
Follow this step-by-step guide to begin using the SDK.
Skip ahead to the Complete Example or explore Advanced Scenarios.
Initialize the SDK with appropriate options:
import "github.com/nebius/gosdk"
sdk, err := gosdk.New(ctx /*, option1, option2, option3 */)
if err != nil {
return fmt.Errorf("create gosdk: %w", err)
}
defer sdk.Close()
The gosdk.New
constructor initializes the SDK.
However, authentication is required for functionality.
Use the gosdk.WithCredentials
option to provide credentials.
To clean up resources properly, ensure you call Close
when finished.
Find all available options in options.go (reference).
Authentication is handled by passing credentials via the gosdk.WithCredentials
option.
Commonly used credentials include gosdk.IAMToken
and gosdk.ServiceAccountReader
.
Find all available credentials in credentials.go (reference).
Supply an IAM token with gosdk.IAMToken
. For instance, if your token is stored in an environment variable:
token := os.Getenv("IAM_TOKEN")
sdk, err := gosdk.New(
ctx,
gosdk.WithCredentials(
gosdk.IAMToken(token),
),
)
To generate an IAM token using the nebius
CLI (documentation):
IAM_TOKEN=$(nebius iam get-access-token)
To authenticate with a service account, provide the service account ID, public key ID, and RSA private key. The SDK uses these details to generate a JWT and exchange it for an IAM token. The token is automatically refreshed in the background to ensure continuous validity.
Use gosdk.ServiceAccount
or gosdk.ServiceAccountReader
with functions from auth/service_account.go.
Here are common approaches:
-
Using a JSON Credentials File:
import "github.com/nebius/gosdk/auth" sdk, err := gosdk.New( ctx, gosdk.WithCredentials( gosdk.ServiceAccountReader( auth.NewServiceAccountCredentialsFileParser( nil, // nil to use the real file system "~/path/to/service_account.json", ), ), ), )
File format:
{ "subject-credentials": { "alg": "RS256", "private-key": "PKCS#8 PEM with new lines escaped as \n", "kid": "public-key-id", "iss": "service-account-id", "sub": "service-account-id" } }
-
Using a PEM-Encoded Private Key File:
auth.NewPrivateKeyFileParser( nil, // nil to use the real file system "~/path/to/private_key.pem", "public-key-id", "service-account-id", )
-
Providing Key Content Directly:
privateKey, _ := os.ReadFile("path/to/private_key.pem") auth.NewPrivateKeyParser( privateKey, "public-key-id", "service-account-id", )
Nebius communicates via gRPC, with read operations such as Get
and List
returning protobuf messages that describe resources.
Mutating operations like Create
, Update
, and Delete
return an Operation
object.
Operations can be either synchronous or asynchronous.
Synchronous operations are completed immediately, while asynchronous operations may take time to finish.
To ensure an operation is fully completed, use the Wait
method, which polls the operation status until it is done.
ℹ️ Note: If the operation fails,
Wait
will return an error.
The following example demonstrates how to create a compute instance and use Wait
to verify the operation's success.
import common "github.com/nebius/gosdk/proto/nebius/common/v1"
import compute "github.com/nebius/gosdk/proto/nebius/compute/v1"
instanceService := sdk.Services().Compute().V1().Instance()
operation, err := instanceService.Create(ctx, &compute.CreateInstanceRequest{
Metadata: &common.ResourceMetadata{
ParentId: "my-project-id",
Name: "my-instance",
},
Spec: &compute.InstanceSpec{
// instance configuration
},
})
if err != nil {
return fmt.Errorf("create instance: %w", err)
}
operation, err = operation.Wait(ctx)
if err != nil {
return fmt.Errorf("wait for instance create: %w", err)
}
instanceID := operation.ResourceID()
The operation doesn't contain the current state of the resource. Once it completes, fetch the resource.
instance, err := instanceService.Get(ctx, &compute.GetInstanceRequest{
Id: instanceID,
})
if err != nil {
return fmt.Errorf("get instance: %w", err)
}
Most resources can also be retrieved using their names.
instance, err = instanceService.GetByName(ctx, &common.GetByNameRequest{
ParentId: "my-project-id",
Name: "my-instance",
})
if err != nil {
return fmt.Errorf("get instance by name: %w", err)
}
When updating, provide a complete resource specification, not just the fields you wish to modify.
Treat the Update
method as having full-replace semantics.
operation, err := instanceService.Update(ctx, &compute.UpdateInstanceRequest{
Metadata: &common.ResourceMetadata{
Id: instanceID,
ParentId: "my-project-id",
Name: "my-instance",
},
Spec: &compute.InstanceSpec{
// new configuration
},
})
if err != nil {
return fmt.Errorf("update instance: %w", err)
}
operation, err = operation.Wait(ctx)
if err != nil {
return fmt.Errorf("wait for instance update: %w", err)
}
The List
method retrieves resources within a specified container.
It supports pagination, which may require additional handling for large number of resources.
list, err := instanceService.List(ctx, &compute.ListInstancesRequest{
ParentId: "my-project-id",
})
if err != nil {
return fmt.Errorf("list instances: %w", err)
}
for _, instance := range list.GetItems() {
// process instance
}
if list.GetNextPageToken() != "" {
list, err = instanceService.List(ctx, &compute.ListInstancesRequest{
ParentId: "my-project-id",
PageToken: list.GetNextPageToken(),
})
if err != nil {
return fmt.Errorf("list instances: %w", err)
}
// repeat processing
}
⚠️ Requires Go 1.23 orGOEXPERIMENT=rangefunc
in Go 1.22.
The Filter
method simplifies resource listing by iterating over items across pages in a single loop.
req := &compute.ListInstancesRequest{ParentId: "my-project-id"}
for instance, err := range instanceService.Filter(ctx, req) {
if err != nil {
return fmt.Errorf("list instances: %w", err)
}
// process instance
}
The following example demonstrates how to delete a compute instance and use Wait
to verify the operation's success.
operation, err := instanceService.Delete(ctx, &compute.DeleteInstanceRequest{
Id: instanceID,
})
if err != nil {
return fmt.Errorf("delete instance: %w", err)
}
operation, err = operation.Wait(ctx)
if err != nil {
return fmt.Errorf("wait for instance delete: %w", err)
}
This example demonstrates how to initialize the SDK with IAM token authentication and perform basic resource operations.
package example
import (
"context"
"fmt"
"os"
"github.com/nebius/gosdk"
common "github.com/nebius/gosdk/proto/nebius/common/v1"
compute "github.com/nebius/gosdk/proto/nebius/compute/v1"
)
func Example() error {
ctx := context.Background()
// Initialize SDK with IAM token
sdk, err := gosdk.New(
ctx,
gosdk.WithCredentials(
gosdk.IAMToken(os.Getenv("IAM_TOKEN")),
),
)
if err != nil {
return fmt.Errorf("create gosdk: %w", err)
}
defer sdk.Close()
instanceService := sdk.Services().Compute().V1().Instance()
// Create resource
operation, err := instanceService.Create(ctx, &compute.CreateInstanceRequest{
Metadata: &common.ResourceMetadata{
ParentId: "my-project-id",
Name: "my-instance",
},
Spec: &compute.InstanceSpec{
// configuration
},
})
if err != nil {
return fmt.Errorf("create instance: %w", err)
}
// Wait for the create operation to complete successfully
operation, err = operation.Wait(ctx)
if err != nil {
return fmt.Errorf("wait for instance creation: %w", err)
}
instanceID := operation.ResourceID()
// Get resource by ID
instance, err := instanceService.Get(ctx, &compute.GetInstanceRequest{
Id: instanceID,
})
if err != nil {
return fmt.Errorf("get instance: %w", err)
}
// Get resource by name
instance, err = instanceService.GetByName(ctx, &common.GetByNameRequest{
ParentId: "my-project-id",
Name: "my-instance",
})
if err != nil {
return fmt.Errorf("get instance by name: %w", err)
}
// Update resource
operation, err = instanceService.Update(ctx, &compute.UpdateInstanceRequest{
Metadata: &common.ResourceMetadata{
Id: instanceID,
ParentId: "my-project-id",
Name: "my-instance",
},
Spec: &compute.InstanceSpec{
// updated configuration
},
})
if err != nil {
return fmt.Errorf("update instance: %w", err)
}
// Wait for update operation complete successfully
operation, err = operation.Wait(ctx)
if err != nil {
return fmt.Errorf("wait for instance update: %w", err)
}
// Iterate over all resources inside container
req := &compute.ListInstancesRequest{ParentId: "my-project-id"}
for instance, err = range instanceService.Filter(ctx, req) {
if err != nil {
return fmt.Errorf("list instances: %w", err)
}
if instance.GetMetadata().GetId() == instanceID {
continue // skip just created instance
}
// Delete resource
operation, err = instanceService.Delete(ctx, &compute.DeleteInstanceRequest{
Id: instance.GetMetadata().GetId(),
})
if err != nil {
return fmt.Errorf("delete instance: %w", err)
}
// Wait for delete operation complete successfully
operation, err = operation.Wait(ctx)
if err != nil {
return fmt.Errorf("wait for instance delete: %w", err)
}
}
return nil
}
Explore advanced usage examples in SCENARIOS.md.
Contributions are welcome! Please refer to the contributing guidelines for more information.
This project is licensed under the MIT License. See the LICENSE file for details.
Copyright (c) 2024 Nebius B.V.