8000 [pull] main from digitalocean:main by pull[bot] · Pull Request #57 · AKJUS/godo · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

[pull] main from digitalocean:main #57

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Change Log

## [v1.156.0] - 2025-07-07

- #862 - @ssaengs - APPS: expose app health
- #863 - @SSharma-10 - Added Anthropic API Key Operations

## [v1.155.0] - 2025-06-26

- #854 - @anup-deka - Implementation for Agent Route and Agent Versions
Expand Down
44 changes: 44 additions & 0 deletions apps.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 19 additions & 1 deletion apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type AppsService interface {

ListBuildpacks(ctx context.Context) ([]*Buildpack, *Response, error)
UpgradeBuildpack(ctx context.Context, appID string, opts UpgradeBuildpackOptions) (*UpgradeBuildpackResponse, *Response, error)

GetAppHealth(ctx context.Context, appID string) (*AppHealth, *Response, error)
GetAppDatabaseConnectionDetails(ctx context.Context, appID string) ([]*GetDatabaseConnectionDetailsResponse, *Response, error)
ResetDatabasePassword(ctx context.Context, appID string, component string) (*Deployment, *Response, error)
ToggleDatabaseTrustedSource(
Expand Down Expand Up @@ -202,6 +202,24 @@ func (a App) URN() string {
return ToURN("app", a.ID)
}

type appHealthRoot struct {
Health *AppHealth `json:"health"`
}

func (s *AppsServiceOp) GetAppHealth(ctx context.Context, appID string) (*AppHealth, *Response, error) {
path := fmt.Sprintf("%s/%s/health", appsBasePath, appID)
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}
root := new(appHealthRoot)
resp, err := s.client.Do(ctx, req, root)
if err != nil {
return nil, resp, err
}
return root.Health, resp, nil
}

// Create an app.
func (s *AppsServiceOp) Create(ctx context.Context, create *AppCreateRequest) (*App, *Response, error) {
path := appsBasePath
Expand Down
32 changes: 32 additions & 0 deletions apps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,38 @@ var (
}
)

func TestApps_GetAppHealth(t *testing.T) {
setup()
defer teardown()

ctx := context.Background()

appHealth := &AppHealth{
Components: []*ComponentHealth{
{
Name: "web",
CPUUsagePercent: 90,
MemoryUsagePercent: 90,
ReplicasDesired: 1,
ReplicasReady: 1,
State: "RUNNING",
},
},
}

mux.HandleFunc("/v2/apps/{id}/health", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)

json.NewEncoder(w).Encode(json.NewEncoder(w).Encode(
appHealthRoot{Health: appHealth},
))
})

appHealthResponse, _, err := client.Apps.GetAppHealth(ctx, testApp.ID)
require.NoError(t, err)
assert.Equal(t, appHealthResponse, appHealth)
}

func TestApps_CreateApp(t *testing.T) {
setup()
defer teardown()
Expand Down
162 changes: 162 additions & 0 deletions genai.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ const (
DeleteKnowledgeBaseByIDPath = KnowledgeBasePath + "/%s"
AgentKnowledgeBasePath = "/v2/gen-ai/agents" + "/%s/knowledge_bases/%s"
DeleteDataSourcePath = KnowledgeBasePath + "/%s/data_sources/%s"
AnthropicAPIKeysPath = "/v2/gen-ai/anthropic/keys"
AnthropicAPIKeyByIDPath = AnthropicAPIKeysPath + "/%s"
)

// GenAIService is an interface for interfacing with the Gen AI Agent endpoints
Expand Down Expand Up @@ -51,6 +53,12 @@ type GenAIService interface {
DeleteAgentRoute(context.Context, string, string) (*AgentRouteResponse, *Response, error)
ListAgentVersions(context.Context, string, *ListOptions) ([]*AgentVersion, *Response, error)
RollbackAgentVersion(context.Context, string, string) (string, *Response, error)
ListAnthropicAPIKeys(context.Context, *ListOptions) ([]*AnthropicApiKeyInfo, *Response, error)
CreateAnthropicAPIKey(ctx context.Context, anthropicAPIKeyCreateRequest *AnthropicAPIKeyCreateRequest) (*AnthropicApiKeyInfo, *Response, error)
GetAnthropicAPIKey(ctx context.Context, id string) (*AnthropicApiKeyInfo, *Response, error)
UpdateAnthropicAPIKey(ctx context.Context, id string, anthropicAPIKeyUpdateRequest *AnthropicAPIKeyUpdateRequest) (*AnthropicApiKeyInfo, *Response, error)
DeleteAnthropicAPIKey(ctx context.Context, id string) (*AnthropicApiKeyInfo, *Response, error)
ListAgentsByAnthropicAPIKey(ctx context.Context, id string, opt *ListOptions) ([]*Agent, *Response, error)
}

var _ GenAIService = &GenAIServiceOp{}
Expand Down Expand Up @@ -92,6 +100,16 @@ type agentVersionsRoot struct {
Meta *Meta `json:"meta,omitempty"`
}

type anthropicAPIKeysRoot struct {
AnthropicApiKeys []*AnthropicApiKeyInfo `json:"api_key_infos"`
Links *Links `json:"links"`
Meta *Meta `json:"meta"`
}

type anthropicAPIKeyRoot struct {
AnthropicApiKey *AnthropicApiKeyInfo `json:"api_key_info,omitempty"`
}

// Agent represents a Gen AI Agent
type Agent struct {
AnthropicApiKey *AnthropicApiKeyInfo `json:"anthropic_api_key,omitempty"`
Expand Down Expand Up @@ -414,6 +432,17 @@ type AgentAPIKeyUpdateRequest struct {
Name string `json:"name,omitempty"`
}

type AnthropicAPIKeyCreateRequest struct {
Name string `json:"name,omitempty"`
ApiKey string `json:"api_key,omitempty"`
}

type AnthropicAPIKeyUpdateRequest struct {
Name string `json:"name,omitempty"`
ApiKey string `json:"api_key,omitempty"`
ApiKeyUuid string `json:"api_key_uuid,omitempty"`
}

type KnowledgeBaseCreateRequest struct {
DatabaseID string `json:"database_id"`
DataSources []KnowledgeBaseDataSource `json:"datasources"`
Expand Down Expand Up @@ -1095,6 +1124,139 @@ func (s *GenAIServiceOp) RollbackAgentVersion(ctx context.Context, agentId strin
return root.VersionHash, resp, nil
}

// ListAnthropicAPIKeys retrieves a list of Anthropic API Keys
func (s *GenAIServiceOp) ListAnthropicAPIKeys(ctx context.Context, opt *ListOptions) ([]*AnthropicApiKeyInfo, *Response, error) {
path := AnthropicAPIKeysPath
path, err := addOptions(path, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

root := new(anthropicAPIKeysRoot)
resp, err := s.client.Do(ctx, req, &root)
if err != nil {
return nil, resp, err
}
if l := root.Links; l != nil {
resp.Links = l
}
if m := root.Meta; m != nil {
resp.Meta = m
}
return root.AnthropicApiKeys, resp, nil
}

func (s *GenAIServiceOp) CreateAnthropicAPIKey(ctx context.Context, anthropicAPIKeyCreate *AnthropicAPIKeyCreateRequest) (*AnthropicApiKeyInfo, *Response, error) {
path := AnthropicAPIKeysPath

if anthropicAPIKeyCreate.Name == "" {
return nil, nil, fmt.Errorf("Name is required")
}
< 6D4E /td> if anthropicAPIKeyCreate.ApiKey == "" {
return nil, nil, fmt.Errorf("ApiKey is required")
}

req, err := s.client.NewRequest(ctx, http.MethodPost, path, anthropicAPIKeyCreate)
if err != nil {
return nil, nil, err
}

root := new(anthropicAPIKeyRoot)
resp, err := s.client.Do(ctx, req, root)
if err != nil {
return nil, resp, err
}

return root.AnthropicApiKey, resp, nil
}

func (s *GenAIServiceOp) GetAnthropicAPIKey(ctx context.Context, anthropicApiKeyId string) (*AnthropicApiKeyInfo, *Response, error) {
path := AnthropicAPIKeysPath + "/" + anthropicApiKeyId

req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

root := new(anthropicAPIKeyRoot)
resp, err := s.client.Do(ctx, req, root)
if err != nil {
return nil, resp, err
}

return root.AnthropicApiKey, resp, nil
}

func (s *GenAIServiceOp) UpdateAnthropicAPIKey(ctx context.Context, anthropicApiKeyId string, anthropicAPIKeyUpdate *AnthropicAPIKeyUpdateRequest) (*AnthropicApiKeyInfo, *Response, error) {
path := AnthropicAPIKeysPath + "/" + anthropicApiKeyId

if anthropicAPIKeyUpdate.ApiKeyUuid == "" {
anthropicAPIKeyUpdate.ApiKeyUuid = anthropicApiKeyId
}
if anthropicAPIKeyUpdate.ApiKeyUuid == "" {
return nil, nil, fmt.Errorf("ApiKeyUuid is required")
}

req, err := s.client.NewRequest(ctx, http.MethodPut, path, anthropicAPIKeyUpdate)
if err != nil {
return nil, nil, err
}

root := new(anthropicAPIKeyRoot)
resp, err := s.client.Do(ctx, req, root)
if err != nil {
return nil, resp, err
}

return root.AnthropicApiKey, resp, nil
}

func (s *GenAIServiceOp) DeleteAnthropicAPIKey(ctx context.Context, anthropicApiKeyId string) (*AnthropicApiKeyInfo, *Response, error) {
path := AnthropicAPIKeysPath + "/" + anthropicApiKeyId

req, err := s.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, nil, err
}

root := new(anthropicAPIKeyRoot)
resp, err := s.client.Do(ctx, req, root)
if err != nil {
return nil, resp, err
}

return root.AnthropicApiKey, resp, nil
}

func (s *GenAIServiceOp) ListAgentsByAnthropicAPIKey(ctx context.Context, anthropicApiKeyId string, opt *ListOptions) ([]*Agent, *Response, error) {
path := fmt.Sprintf("%s/%s/agents", AnthropicAPIKeysPath, anthropicApiKeyId)
path, err := addOptions(path, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

root := new(genAIAgentsRoot)
resp, err := s.client.Do(ctx, req, root)
if err != nil {
return nil, resp, err
}
if l := root.Links; l != nil {
resp.Links = l
}
if m := root.Meta; m != nil {
resp.Meta = m
}
return root.Agents, resp, nil
}

func (a Agent) String() string {
return Stringify(a)
}
Expand Down
Loading
0