feat: simplify acquiring access on new-api
This commit is contained in:
parent
0d017e24bc
commit
8c872e3c35
3 changed files with 62 additions and 32 deletions
|
|
@ -5,8 +5,8 @@
|
||||||
# ============================================
|
# ============================================
|
||||||
|
|
||||||
# --- new-api (LLM proxy) ---
|
# --- new-api (LLM proxy) ---
|
||||||
# Admin access token for new-api management API (also used by init-channels.sh)
|
# Admin password (used by init-channels.sh to login and configure channels)
|
||||||
NEW_API_ACCESS_TOKEN=change-me-to-a-random-string
|
NEW_API_PASSWORD=change-me-after-first-login
|
||||||
OPENROUTER_API_KEY=sk-or-...
|
OPENROUTER_API_KEY=sk-or-...
|
||||||
SILICONFLOW_API_KEY=sk-...
|
SILICONFLOW_API_KEY=sk-...
|
||||||
DEEPINFRA_API_KEY=...
|
DEEPINFRA_API_KEY=...
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,6 @@ services:
|
||||||
- TZ=UTC
|
- TZ=UTC
|
||||||
- ENABLE_METRIC=true
|
- ENABLE_METRIC=true
|
||||||
- LANG=en_US.UTF-8
|
- LANG=en_US.UTF-8
|
||||||
- INITIAL_ROOT_ACCESS_TOKEN=${NEW_API_ACCESS_TOKEN}
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost:3000/"]
|
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://localhost:3000/"]
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,13 @@
|
||||||
# Run once after first boot: ./new-api/init-channels.sh
|
# Run once after first boot: ./new-api/init-channels.sh
|
||||||
#
|
#
|
||||||
# Requires these env vars (or .env file in project root):
|
# Requires these env vars (or .env file in project root):
|
||||||
# NEW_API_ACCESS_TOKEN - admin access token (set via INITIAL_ROOT_ACCESS_TOKEN)
|
# NEW_API_USERNAME - admin username (default: root)
|
||||||
|
# NEW_API_PASSWORD - admin password
|
||||||
# DEEPINFRA_API_KEY
|
# DEEPINFRA_API_KEY
|
||||||
# SILICONFLOW_API_KEY
|
# SILICONFLOW_API_KEY
|
||||||
# OPENROUTER_API_KEY
|
# OPENROUTER_API_KEY
|
||||||
# GROQ_API_KEY
|
# GROQ_API_KEY
|
||||||
# CEREBRAS_API_KEY
|
# CEREBRAS_API_KEY
|
||||||
# OPENWEBUI_API_KEY - token for Open WebUI to authenticate with new-api
|
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
|
@ -25,7 +25,30 @@ if [[ -f "$ENV_FILE" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
API_BASE="${NEW_API_BASE:-http://localhost:4000}"
|
API_BASE="${NEW_API_BASE:-http://localhost:4000}"
|
||||||
TOKEN="${NEW_API_ACCESS_TOKEN:?Set NEW_API_ACCESS_TOKEN (from INITIAL_ROOT_ACCESS_TOKEN)}"
|
USERNAME="${NEW_API_USERNAME:-root}"
|
||||||
|
PASSWORD="${NEW_API_PASSWORD:?Set NEW_API_PASSWORD to the admin password}"
|
||||||
|
|
||||||
|
# ── Login to get session token ──────────────────────────
|
||||||
|
login() {
|
||||||
|
echo "Logging in as ${USERNAME}..."
|
||||||
|
local resp
|
||||||
|
resp=$(curl -s "${API_BASE}/api/user/login" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$(python3 -c "
|
||||||
|
import json, sys
|
||||||
|
print(json.dumps({'username': sys.argv[1], 'password': sys.argv[2]}))
|
||||||
|
" "$USERNAME" "$PASSWORD")")
|
||||||
|
|
||||||
|
local success token
|
||||||
|
success=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('success', False))")
|
||||||
|
if [[ "$success" != "True" ]]; then
|
||||||
|
echo "ERROR: Login failed: ${resp}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TOKEN=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['access_token'])")
|
||||||
|
echo " Logged in."
|
||||||
|
}
|
||||||
|
|
||||||
# ── Helper ──────────────────────────────────────────────
|
# ── Helper ──────────────────────────────────────────────
|
||||||
create_channel() {
|
create_channel() {
|
||||||
|
|
@ -51,21 +74,17 @@ print(json.dumps({
|
||||||
}))
|
}))
|
||||||
" "$type" "$name" "$key" "$base_url" "$models" "$model_mapping" "$priority")
|
" "$type" "$name" "$key" "$base_url" "$models" "$model_mapping" "$priority")
|
||||||
|
|
||||||
local resp http_code body
|
local resp success
|
||||||
resp=$(curl -s -w "\n%{http_code}" \
|
resp=$(curl -s "${API_BASE}/api/channel/" \
|
||||||
"${API_BASE}/api/channel/" \
|
|
||||||
-H "Authorization: Bearer ${TOKEN}" \
|
-H "Authorization: Bearer ${TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d "$payload")
|
-d "$payload")
|
||||||
|
|
||||||
http_code=$(echo "$resp" | tail -1)
|
success=$(echo "$resp" | python3 -c "import sys,json; print(json.load(sys.stdin).get('success', False))")
|
||||||
body=$(echo "$resp" | sed '$d')
|
if [[ "$success" == "True" ]]; then
|
||||||
|
|
||||||
if [[ "$http_code" == "200" ]]; then
|
|
||||||
echo " OK"
|
echo " OK"
|
||||||
else
|
else
|
||||||
echo " FAILED (HTTP ${http_code})"
|
echo " FAILED: ${resp}" | head -c 500
|
||||||
echo " ${body}" | head -c 500
|
|
||||||
echo
|
echo
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +92,7 @@ print(json.dumps({
|
||||||
# Wait for new-api to be ready
|
# Wait for new-api to be ready
|
||||||
echo "Waiting for new-api at ${API_BASE}..."
|
echo "Waiting for new-api at ${API_BASE}..."
|
||||||
for i in $(seq 1 30); do
|
for i in $(seq 1 30); do
|
||||||
if curl -sf "${API_BASE}/api/status" > /dev/null 2>&1; then
|
if curl -sf "${API_BASE}/" > /dev/null 2>&1; then
|
||||||
echo "new-api is ready."
|
echo "new-api is ready."
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
@ -84,6 +103,9 @@ for i in $(seq 1 30); do
|
||||||
sleep 2
|
sleep 2
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Login first
|
||||||
|
login
|
||||||
|
|
||||||
# ── Channel: DeepInfra (priority 1) ────────────────────
|
# ── Channel: DeepInfra (priority 1) ────────────────────
|
||||||
create_channel "DeepInfra" 1 \
|
create_channel "DeepInfra" 1 \
|
||||||
"${DEEPINFRA_API_KEY:?}" \
|
"${DEEPINFRA_API_KEY:?}" \
|
||||||
|
|
@ -125,13 +147,12 @@ create_channel "Cerebras" 1 \
|
||||||
'{"llama-3.3-70b-cerebras":"llama-3.3-70b"}'
|
'{"llama-3.3-70b-cerebras":"llama-3.3-70b"}'
|
||||||
|
|
||||||
# ── Create API token for Open WebUI ────────────────────
|
# ── Create API token for Open WebUI ────────────────────
|
||||||
if [[ -n "${OPENWEBUI_API_KEY:-}" ]]; then
|
echo ""
|
||||||
echo ""
|
echo "Creating API token for Open WebUI..."
|
||||||
echo "Creating API token for Open WebUI..."
|
TOKEN_RESP=$(curl -s "${API_BASE}/api/token/" \
|
||||||
TOKEN_RESP=$(curl -s "${API_BASE}/api/token/" \
|
-H "Authorization: Bearer ${TOKEN}" \
|
||||||
-H "Authorization: Bearer ${TOKEN}" \
|
-H "Content-Type: application/json" \
|
||||||
-H "Content-Type: application/json" \
|
-d "$(python3 -c "
|
||||||
-d "$(python3 -c "
|
|
||||||
import json
|
import json
|
||||||
print(json.dumps({
|
print(json.dumps({
|
||||||
'name': 'open-webui',
|
'name': 'open-webui',
|
||||||
|
|
@ -139,23 +160,33 @@ print(json.dumps({
|
||||||
'unlimited_quota': True
|
'unlimited_quota': True
|
||||||
}))
|
}))
|
||||||
")")
|
")")
|
||||||
echo "Token response: ${TOKEN_RESP}" | head -c 500
|
|
||||||
echo ""
|
TOKEN_KEY=$(echo "$TOKEN_RESP" | python3 -c "
|
||||||
echo ""
|
import sys, json
|
||||||
echo "NOTE: Use the token 'key' from the response above as OPENAI_API_KEY in Open WebUI."
|
data = json.load(sys.stdin)
|
||||||
echo " Or create a token manually in the new-api UI."
|
if data.get('success'):
|
||||||
fi
|
print(data['data']['key'])
|
||||||
|
else:
|
||||||
|
print('FAILED: ' + data.get('message', 'unknown error'))
|
||||||
|
" 2>/dev/null || echo "FAILED: could not parse response")
|
||||||
|
|
||||||
|
echo " Token: ${TOKEN_KEY}"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "══════════════════════════════════════"
|
echo "══════════════════════════════════════"
|
||||||
echo "Channel setup complete!"
|
echo "Channel setup complete!"
|
||||||
echo ""
|
echo ""
|
||||||
|
if [[ "$TOKEN_KEY" != FAILED* ]]; then
|
||||||
|
echo "Open WebUI API key: ${TOKEN_KEY}"
|
||||||
|
echo "Set OPENWEBUI_API_KEY=${TOKEN_KEY} in your .env"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
echo "Next steps:"
|
echo "Next steps:"
|
||||||
echo " 1. Verify channels at ${API_BASE} (login: root / 123456 — CHANGE THIS)"
|
echo " 1. Verify channels at ${API_BASE}"
|
||||||
echo " 2. Test a model:"
|
echo " 2. Test a model:"
|
||||||
echo " curl ${API_BASE}/v1/chat/completions \\"
|
echo " curl ${API_BASE}/v1/chat/completions \\"
|
||||||
echo " -H 'Authorization: Bearer <token>' \\"
|
echo " -H 'Authorization: Bearer ${TOKEN_KEY}' \\"
|
||||||
echo " -H 'Content-Type: application/json' \\"
|
echo " -H 'Content-Type: application/json' \\"
|
||||||
echo " -d '{\"model\":\"deepseek-v3.2\",\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}]}'"
|
echo " -d '{\"model\":\"deepseek-v3.2\",\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}]}'"
|
||||||
echo " 3. Check Open WebUI can see models"
|
echo " 3. Restart Open WebUI with the new API key"
|
||||||
echo "══════════════════════════════════════"
|
echo "══════════════════════════════════════"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue