-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.go
More file actions
146 lines (123 loc) · 3.96 KB
/
Copy pathclient.go
File metadata and controls
146 lines (123 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"time"
)
// SandboxClient calls the SandboxAPI HTTP API.
type SandboxClient struct {
baseURL string
apiKey string
httpClient *http.Client
}
// NewSandboxClient creates a client for the SandboxAPI HTTP API.
func NewSandboxClient(baseURL, apiKey string) *SandboxClient {
return &SandboxClient{
baseURL: baseURL,
apiKey: apiKey,
httpClient: &http.Client{
Timeout: 5 * time.Minute,
},
}
}
// ExecuteRequest is the request body for POST /v1/execute.
type ExecuteRequest struct {
Language string `json:"language"`
Code string `json:"code"`
Timeout int `json:"timeout,omitempty"`
Stdin string `json:"stdin,omitempty"`
}
// ExecuteResult is the response from POST /v1/execute.
type ExecuteResult struct {
ID string `json:"id"`
Status string `json:"status"`
Language string `json:"language"`
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
ExitCode int `json:"exit_code"`
ExecutionTimeMs int64 `json:"execution_time_ms"`
MemoryUsedKB int64 `json:"memory_used_kb"`
}
// LanguageInfo is the response shape for each language from GET /v1/languages.
type LanguageInfo struct {
ID string `json:"id"`
Name string `json:"name"`
Version string `json:"version"`
Aliases []string `json:"aliases"`
FileExtension string `json:"file_extension"`
Example string `json:"example"`
}
// LanguageListResponse is the response from GET /v1/languages.
type LanguageListResponse struct {
Languages []LanguageInfo `json:"languages"`
}
// APIError represents an error response from the API.
type APIError struct {
Error string `json:"error"`
Message string `json:"message"`
}
// Execute sends code to the SandboxAPI for execution.
func (c *SandboxClient) Execute(ctx context.Context, req ExecuteRequest) (*ExecuteResult, error) {
body, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("marshal request: %w", err)
}
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost,
c.baseURL+"/v1/execute", bytes.NewReader(body))
if err != nil {
return nil, fmt.Errorf("create request: %w", err)
}
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("X-RapidAPI-Proxy-Secret", c.apiKey)
resp, err := c.httpClient.Do(httpReq)
if err != nil {
return nil, fmt.Errorf("execute request: %w", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
var apiErr APIError
if json.Unmarshal(respBody, &apiErr) == nil && apiErr.Error != "" {
return nil, fmt.Errorf("API error (%d): %s", resp.StatusCode, apiErr.Error)
}
return nil, fmt.Errorf("API error (%d): %s", resp.StatusCode, string(respBody))
}
var result ExecuteResult
if err := json.Unmarshal(respBody, &result); err != nil {
return nil, fmt.Errorf("unmarshal response: %w", err)
}
return &result, nil
}
// ListLanguages fetches the list of supported languages from the API.
func (c *SandboxClient) ListLanguages(ctx context.Context) ([]LanguageInfo, error) {
httpReq, err := http.NewRequestWithContext(ctx, http.MethodGet,
c.baseURL+"/v1/languages", nil)
if err != nil {
return nil, fmt.Errorf("create request: %w", err)
}
httpReq.Header.Set("X-RapidAPI-Proxy-Secret", c.apiKey)
resp, err := c.httpClient.Do(httpReq)
if err != nil {
return nil, fmt.Errorf("list languages request: %w", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API error (%d): %s", resp.StatusCode, string(respBody))
}
var listResp LanguageListResponse
if err := json.Unmarshal(respBody, &listResp); err != nil {
return nil, fmt.Errorf("unmarshal response: %w", err)
}
return listResp.Languages, nil
}