Skip to content

Commit ad5e4ad

Browse files
authored
Merge pull request #75 from Pangjiping/hotfix/server/v1
feat(server): add v1 router
2 parents 54a2299 + 065529f commit ad5e4ad

File tree

5 files changed

+33
-23
lines changed

5 files changed

+33
-23
lines changed

server/README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,15 @@ Authentication is enforced only when `server.api_key` is set. If the value is em
149149
All API endpoints (except `/health`, `/docs`, `/redoc`) require authentication via the `OPEN-SANDBOX-API-KEY` header when authentication is enabled:
150150

151151
```bash
152-
curl http://localhost:8080/sandboxes
152+
curl http://localhost:8080/v1/sandboxes
153153
```
154154

155155
### Example usage
156156

157157
**Create a Sandbox**
158158

159159
```bash
160-
curl -X POST "http://localhost:8080/sandboxes" \
160+
curl -X POST "http://localhost:8080/v1/sandboxes" \
161161
-H "OPEN-SANDBOX-API-KEY: your-secret-api-key" \
162162
-H "Content-Type: application/json" \
163163
-d '{
@@ -209,18 +209,18 @@ Response:
209209

210210
```bash
211211
curl -H "OPEN-SANDBOX-API-KEY: your-secret-api-key" \
212-
http://localhost:8080/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab
212+
http://localhost:8080/v1/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab
213213
```
214214

215215
**Get Service Endpoint**
216216

217217
```bash
218218
curl -H "OPEN-SANDBOX-API-KEY: your-secret-api-key" \
219-
http://localhost:8080/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab/endpoints/8000
219+
http://localhost:8080/v1/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab/endpoints/8000
220220

221221
# execd (agent) endpoint
222222
curl -H "OPEN-SANDBOX-API-KEY: your-secret-api-key" \
223-
http://localhost:8080/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab/endpoints/44772
223+
http://localhost:8080/v1/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab/endpoints/44772
224224
```
225225

226226
Response:
@@ -233,7 +233,7 @@ Response:
233233
**Renew Expiration**
234234

235235
```bash
236-
curl -X POST "http://localhost:8080/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab/renew-expiration" \
236+
curl -X POST "http://localhost:8080/v1/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab/renew-expiration" \
237237
-H "OPEN-SANDBOX-API-KEY: your-secret-api-key" \
238238
-H "Content-Type: application/json" \
239239
-d '{
@@ -246,7 +246,7 @@ curl -X POST "http://localhost:8080/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890
246246
```bash
247247
curl -X DELETE \
248248
-H "OPEN-SANDBOX-API-KEY: your-secret-api-key" \
249-
http://localhost:8080/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab
249+
http://localhost:8080/v1/sandboxes/a1b2c3d4-5678-90ab-cdef-1234567890ab
250250
```
251251

252252
## Architecture

server/README_zh.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,15 @@ curl http://localhost:8080/health
152152
当鉴权开启时,除 `/health``/docs``/redoc` 外的 API 端点均需要通过 `OPEN-SANDBOX-API-KEY` 请求头进行认证:
153153

154154
```bash
155-
curl http://localhost:8080/sandboxes
155+
curl http://localhost:8080/v1/sandboxes
156156
```
157157

158158
### 使用示例
159159

160160
**创建沙箱**
161161

162162
```bash
163-
curl -X POST "http://localhost:8080/sandboxes" \
163+
curl -X POST "http://localhost:8080/v1/sandboxes" \
164164
-H "Content-Type: application/json" \
165165
-d '{
166166
"image": {
@@ -210,17 +210,17 @@ curl -X POST "http://localhost:8080/sandboxes" \
210210
**获取沙箱详情**
211211

212212
```bash
213-
curl http://localhost:8080/sandboxes/<sandbox-id>
213+
curl http://localhost:8080/v1/sandboxes/<sandbox-id>
214214
```
215215

216216
**获取服务端点**
217217

218218
```bash
219219
# 获取自定义服务端点
220-
curl http://localhost:8080/sandboxes/<sandbox-id>/endpoints/8000
220+
curl http://localhost:8080/v1/sandboxes/<sandbox-id>/endpoints/8000
221221

222222
# 获取OpenSandbox守护进程(execd)端点
223-
curl http://localhost:8080/sandboxes/<sandbox-id>/endpoints/44772
223+
curl http://localhost:8080/v1/sandboxes/<sandbox-id>/endpoints/44772
224224
```
225225

226226
响应:
@@ -233,7 +233,7 @@ curl http://localhost:8080/sandboxes/<sandbox-id>/endpoints/44772
233233
**续期沙箱**
234234

235235
```bash
236-
curl -X POST "http://localhost:8080/sandboxes/<sandbox-id>/renew-expiration" \
236+
curl -X POST "http://localhost:8080/v1/sandboxes/<sandbox-id>/renew-expiration" \
237237
-H "Content-Type: application/json" \
238238
-d '{
239239
"expiresAt": "2024-01-15T12:30:00Z"
@@ -243,7 +243,7 @@ curl -X POST "http://localhost:8080/sandboxes/<sandbox-id>/renew-expiration" \
243243
**删除沙箱**
244244

245245
```bash
246-
curl -X DELETE http://localhost:8080/sandboxes/<sandbox-id>
246+
curl -X DELETE http://localhost:8080/v1/sandboxes/<sandbox-id>
247247
```
248248

249249
## 系统架构

server/src/main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,9 @@
8888
# Add authentication middleware
8989
app.add_middleware(AuthMiddleware, config=app_config)
9090

91-
# Include API routes at root
91+
# Include API routes at root and versioned prefix
9292
app.include_router(router)
93+
app.include_router(router, prefix="/v1")
9394

9495
DEFAULT_ERROR_CODE = "GENERAL::UNKNOWN_ERROR"
9596
DEFAULT_ERROR_MESSAGE = "An unexpected error occurred."

server/tests/smoke.sh

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ error() {
5050
}
5151

5252
BASE_URL="${BASE_URL:-http://localhost:32888}"
53+
BASE_API_URL="${BASE_URL}/v1"
5354
API_KEY_HEADER=()
5455
if [[ -n "${OPEN_SANDBOX_API_KEY:-}" ]]; then
5556
API_KEY_HEADER=(-H "OPEN-SANDBOX-API-KEY: ${OPEN_SANDBOX_API_KEY}")
@@ -68,7 +69,7 @@ wait_for_running() {
6869
local deadline=$((SECONDS + 10))
6970
while true; do
7071
local resp
71-
resp=$(curl_json "${BASE_URL}/sandboxes/${SANDBOX_ID}")
72+
resp=$(curl_json "${BASE_API_URL}/sandboxes/${SANDBOX_ID}")
7273
local state
7374
state=$(python - <<'PY' "${resp}"
7475
import json,sys
@@ -97,7 +98,7 @@ wait_for_expired() {
9798
local deadline=$((SECONDS + 90))
9899
while true; do
99100
local resp body status
100-
resp=$(curl_json_status "${BASE_URL}/sandboxes/${sandbox_id}")
101+
resp=$(curl_json_status "${BASE_API_URL}/sandboxes/${sandbox_id}")
101102
status="${resp##*$'\n'}"
102103
body="${resp%$'\n'*}"
103104
if [[ "${status}" == "404" ]]; then
@@ -128,7 +129,7 @@ step "Create sandbox (60s TTL)"
128129
create_resp=$(curl_json \
129130
-H 'Content-Type: application/json' \
130131
-d "${create_payload}" \
131-
"${BASE_URL}/sandboxes")
132+
"${BASE_API_URL}/sandboxes")
132133

133134
SANDBOX_ID=$(python - <<'PY' "${create_resp}"
134135
import json,sys
@@ -166,7 +167,7 @@ list_resp=$(curl_json \
166167
--data-urlencode "metadata=hello=world" \
167168
--data-urlencode "page=1" \
168169
--data-urlencode "pageSize=10" \
169-
"${BASE_URL}/sandboxes")
170+
"${BASE_API_URL}/sandboxes")
170171

171172
python - <<'PY' "${list_resp}" "${SANDBOX_ID}"
172173
import json,sys
@@ -196,7 +197,7 @@ renew_resp=$(curl_json \
196197
-X POST \
197198
-H 'Content-Type: application/json' \
198199
-d "${renew_payload}" \
199-
"${BASE_URL}/sandboxes/${SANDBOX_ID}/renew-expiration")
200+
"${BASE_API_URL}/sandboxes/${SANDBOX_ID}/renew-expiration")
200201
renewed=$(python - <<'PY' "${renew_resp}"
201202
import json,sys
202203
body=json.loads(sys.argv[1])
@@ -206,7 +207,7 @@ PY
206207
echo "Expiration renewed to: ${renewed}"
207208

208209
step "Request endpoint on port 8080"
209-
endpoint_resp=$(curl_json "${BASE_URL}/sandboxes/${SANDBOX_ID}/endpoints/8080")
210+
endpoint_resp=$(curl_json "${BASE_API_URL}/sandboxes/${SANDBOX_ID}/endpoints/8080")
210211
endpoint=$(python - <<'PY' "${endpoint_resp}"
211212
import json,sys
212213
body=json.loads(sys.argv[1])
@@ -216,7 +217,7 @@ PY
216217
echo "Endpoint: ${endpoint}"
217218

218219
step "Delete sandbox"
219-
curl_json -X DELETE "${BASE_URL}/sandboxes/${SANDBOX_ID}"
220+
curl_json -X DELETE "${BASE_API_URL}/sandboxes/${SANDBOX_ID}"
220221
echo "Sandbox ${SANDBOX_ID} deleted."
221222

222223
step "Create short-lived sandbox (60s TTL) for auto-expiration"
@@ -232,7 +233,7 @@ create_payload_short='{
232233
create_resp_short=$(curl_json \
233234
-H 'Content-Type: application/json' \
234235
-d "${create_payload_short}" \
235-
"${BASE_URL}/sandboxes")
236+
"${BASE_API_URL}/sandboxes")
236237

237238
SANDBOX_ID=$(python - <<'PY' "${create_resp_short}"
238239
import json,sys

server/tests/test_routes.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ def test_missing_api_key(self, client: TestClient):
5050
assert response.status_code == 401
5151
assert "MISSING_API_KEY" in response.json()["code"]
5252

53+
def test_missing_api_key_v1_prefix(self, client: TestClient):
54+
"""
55+
Test request without API key on versioned route returns 401.
56+
"""
57+
response = client.get("/v1/sandboxes/123e4567-e89b-12d3-a456-426614174000")
58+
assert response.status_code == 401
59+
assert "MISSING_API_KEY" in response.json()["code"]
60+
5361
def test_invalid_api_key(self, client: TestClient):
5462
"""
5563
Test request with invalid API key returns 401.

0 commit comments

Comments
 (0)