diff --git a/scripts/QUICKSTART.md b/scripts/QUICKSTART.md new file mode 100644 index 0000000..e9e525b --- /dev/null +++ b/scripts/QUICKSTART.md @@ -0,0 +1,89 @@ +# ๐Ÿš€ Quick Start Guide + +Get the Z.AI to OpenAI API proxy running in 60 seconds! + +## One-Command Setup + +```bash +git clone https://github.com/Zeeeepa/z.ai2api_python.git +cd z.ai2api_python + +# Optional: Set credentials +export ZAI_EMAIL="developer@pixelium.uk" +export ZAI_PASSWORD="developer123?" +export SERVER_PORT=7322 + +# Deploy, start, and test +bash scripts/all.sh +``` + +## What You Get + +โœ… **Server running** on http://localhost:7322 (or next available port) +โœ… **API endpoint** at http://localhost:7322/v1 +โœ… **Automatic test** with working response +โœ… **Ready for production** or development use + +## Test with cURL + +```bash +curl -X POST "http://localhost:7322/v1/chat/completions" \ + -H "Authorization: Bearer sk-any" \ + -H "Content-Type: application/json" \ + -d '{ + "model": "gpt-5", + "messages": [ + {"role": "user", "content": "Hello!"} + ] + }' +``` + +## Test with Python + +```python +from openai import OpenAI + +client = OpenAI( + api_key="sk-any", + base_url="http://localhost:7322/v1" +) + +response = client.chat.completions.create( + model="gpt-5", + messages=[{"role": "user", "content": "Hello!"}] +) + +print(response.choices[0].message.content) +``` + +## Common Commands + +```bash +# View logs +tail -f server.log + +# Stop server +kill $(cat server.pid) + +# Restart server +bash scripts/start.sh + +# Run test +bash scripts/send_openai_request.sh +``` + +## File Locations + +- **Logs:** `server.log` +- **PID:** `server.pid` +- **Port:** `server.port` +- **Scripts:** `scripts/` + +## Need Help? + +See [scripts/README.md](README.md) for detailed documentation. + +--- + +**That's it! ๐ŸŽ‰ Your proxy is ready to use!** + diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..87e32c0 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,417 @@ +# Z.AI to OpenAI API Proxy - Deployment Scripts + +Automated deployment and testing scripts for the z.ai2api_python proxy server. + +## Quick Start + +```bash +# Clone the repository +git clone https://github.com/Zeeeepa/z.ai2api_python.git +cd z.ai2api_python + +# Set credentials (optional - will use anonymous mode if not set) +export ZAI_EMAIL="your-email@example.com" +export ZAI_PASSWORD="your-password" +export SERVER_PORT=7322 # Optional, defaults to 7300 + +# Run everything +bash scripts/all.sh +``` + +That's it! The server will be deployed, started, and tested automatically. + +## Individual Scripts + +### 1. `deploy.sh` - Dependency Installation + +Installs all dependencies and sets up the virtual environment. + +```bash +bash scripts/deploy.sh +``` + +**What it does:** +- โœ… Checks for `uv` installation +- โœ… Creates Python virtual environment (`.venv/`) +- โœ… Installs project dependencies via `uv sync` +- โœ… Installs OpenAI client library for testing + +**Requirements:** +- `uv` must be installed ([installation guide](https://github.com/astral-sh/uv)) + +**Exit Codes:** +- `0` - Success +- `1` - Missing required files (main.py, pyproject.toml) +- `2` - `uv` not installed + +--- + +### 2. `start.sh` - Server Startup with Port Fallback + +Starts the server with intelligent port selection. + +```bash +bash scripts/start.sh +``` + +**What it does:** +- โœ… Finds available port (tries 7300 โ†’ 7301 โ†’ 7302, etc.) +- โœ… Starts server in background +- โœ… Waits for server to be ready +- โœ… Saves PID to `server.pid` and port to `server.port` + +**Environment Variables:** +- `SERVER_PORT` - Starting port (default: 7300) +- `ZAI_EMAIL` - Your Z.AI email (optional) +- `ZAI_PASSWORD` - Your Z.AI password (optional) +- `AUTH_TOKEN` - API key for clients (default: "sk-any") + +**Port Detection:** +The script tries up to 10 ports starting from `SERVER_PORT`. If all are busy, it exits with an error. + +**Output Files:** +- `server.log` - Server logs +- `server.pid` - Server process ID +- `server.port` - Selected port number + +**Exit Codes:** +- `0` - Success +- `1` - Virtual environment not found +- `3` - No available port found +- `4` - Server failed to start + +--- + +### 3. `send_openai_request.sh` - API Testing + +Sends a test OpenAI API request to verify the server is working. + +```bash +bash scripts/send_openai_request.sh +``` + +**What it does:** +- โœ… Reads server port from `server.port` +- โœ… Verifies server is running (checks PID) +- โœ… Sends chat completion request +- โœ… Displays response and timing + +**Test Request:** +```python +{ + "model": "gpt-5", + "messages": [ + {"role": "user", "content": "Write a haiku about code."} + ] +} +``` + +**Exit Codes:** +- `0` - Success +- `1` - Virtual environment not found +- `4` - Server not running +- `5` - API request failed + +--- + +### 4. `all.sh` - Complete Setup (Recommended) + +Runs all scripts in sequence with nice formatting. + +```bash +bash scripts/all.sh +``` + +**Execution Order:** +1. `deploy.sh` - Install dependencies +2. `start.sh` - Start server +3. `send_openai_request.sh` - Test API + +**Features:** +- ๐ŸŽจ Colored output +- ๐Ÿ“Š Environment display +- โŒ Fail-fast behavior (stops on first error) +- โœ… Success summary with useful commands + +--- + +## Usage Examples + +### Example 1: Basic Setup (Anonymous Mode) + +```bash +cd z.ai2api_python +bash scripts/all.sh +``` + +Server will run in anonymous mode without Z.AI credentials. + +### Example 2: With Z.AI Credentials + +```bash +export ZAI_EMAIL="developer@pixelium.uk" +export ZAI_PASSWORD="developer123?" +export SERVER_PORT=7322 + +cd z.ai2api_python +bash scripts/all.sh +``` + +Server will authenticate with Z.AI using provided credentials. + +### Example 3: Custom Port + +```bash +export SERVER_PORT=8080 +bash scripts/all.sh +``` + +Server will try port 8080 first, then 8081, 8082, etc. if busy. + +### Example 4: Step-by-Step Execution + +```bash +# Step 1: Deploy +bash scripts/deploy.sh + +# Step 2: Start server +export ZAI_EMAIL="your@email.com" +export ZAI_PASSWORD="yourpass" +bash scripts/start.sh + +# Step 3: Test API +bash scripts/send_openai_request.sh +``` + +--- + +## Server Management + +### View Logs + +```bash +tail -f server.log +``` + +### Stop Server + +```bash +kill $(cat server.pid) +``` + +### Restart Server + +```bash +# Stop current server +kill $(cat server.pid) + +# Start new server +bash scripts/start.sh +``` + +### Check Server Status + +```bash +# Check if process is running +ps -p $(cat server.pid) + +# Get server port +cat server.port + +# Test server endpoint +curl http://localhost:$(cat server.port)/v1/models +``` + +--- + +## Troubleshooting + +### Error: "uv is not installed" + +**Solution:** +```bash +curl -LsSf https://astral.sh/uv/install.sh | sh +``` + +### Error: "No available port found" + +**Solution:** +- Check what's using ports: `lsof -ti:7300-7310` +- Kill processes or set different `SERVER_PORT` +- Example: `export SERVER_PORT=8000` + +### Error: "Server failed to start" + +**Solution:** +```bash +# Check logs +cat server.log + +# Common issues: +# 1. Port already in use +# 2. Missing dependencies +# 3. Python version mismatch + +# Try manual start for debugging +PYTHONPATH= ./.venv/bin/python main.py +``` + +### Error: "Virtual environment not found" + +**Solution:** +```bash +# Run deploy script first +bash scripts/deploy.sh +``` + +### API Request Fails + +**Solution:** +```bash +# 1. Verify server is running +ps aux | grep "python main.py" + +# 2. Check port +cat server.port + +# 3. Test with curl +PORT=$(cat server.port) +curl -X POST "http://localhost:$PORT/v1/chat/completions" \ + -H "Authorization: Bearer sk-any" \ + -H "Content-Type: application/json" \ + -d '{"model":"gpt-5","messages":[{"role":"user","content":"test"}]}' + +# 4. Check logs +tail -50 server.log +``` + +### Error: "Z.AI API ้”™่ฏฏ: 405" or "ๅŒฟๅๆจกๅผไธ‹่Žทๅ–่ฎฟๅฎขไปค็‰Œๅคฑ่ดฅ" + +This error indicates that Z.AI's authentication API has changed or is temporarily unavailable. + +**Solutions:** + +1. **Use authenticated mode with credentials:** + ```bash + export ZAI_EMAIL="your-email@example.com" + export ZAI_PASSWORD="your-password" + bash scripts/start.sh + ``` + +2. **Check Z.AI service status:** + - Visit https://chat.z.ai/ to verify the service is operational + - The anonymous token endpoint may have changed + +3. **Wait and retry:** + - Z.AI may be experiencing temporary issues + - The service typically recovers within a few minutes + +--- + +## Environment Variables Reference + +| Variable | Default | Description | +|----------|---------|-------------| +| `SERVER_PORT` | `7300` | Starting port for server | +| `ZAI_EMAIL` | (none) | Z.AI account email | +| `ZAI_PASSWORD` | (none) | Z.AI account password | +| `AUTH_TOKEN` | `"sk-any"` | API key for client requests | +| `LISTEN_PORT` | Auto | Actual port selected by start.sh | + +--- + +## File Structure + +``` +z.ai2api_python/ +โ”œโ”€โ”€ scripts/ +โ”‚ โ”œโ”€โ”€ deploy.sh # Install dependencies +โ”‚ โ”œโ”€โ”€ start.sh # Start server +โ”‚ โ”œโ”€โ”€ send_openai_request.sh # Test API +โ”‚ โ”œโ”€โ”€ all.sh # Run all scripts +โ”‚ โ””โ”€โ”€ README.md # This file +โ”œโ”€โ”€ server.log # Server logs (generated) +โ”œโ”€โ”€ server.pid # Server PID (generated) +โ””โ”€โ”€ server.port # Server port (generated) +``` + +--- + +## Advanced Usage + +### Run in Docker + +**Note:** A Dockerfile is not currently included in this repository. To run with Docker, you'll need to create a Dockerfile first. Example: + +```dockerfile +FROM python:3.11-slim +WORKDIR /app +COPY . . +RUN pip install uv && uv venv && uv sync +CMD ["bash", "scripts/start.sh"] +``` + +Then build and run: + +```bash +# Build image +docker build -t z-ai2api . + +# Run container +docker run -d \ + -p 7300:7300 \ + -e ZAI_EMAIL="your@email.com" \ + -e ZAI_PASSWORD="yourpass" \ + --name z-ai2api \ + z-ai2api +``` + +### Use with systemd + +Create `/etc/systemd/system/z-ai2api.service`: + +```ini +[Unit] +Description=Z.AI to OpenAI API Proxy +After=network.target + +[Service] +Type=forking +User=youruser +WorkingDirectory=/path/to/z.ai2api_python +Environment="ZAI_EMAIL=your@email.com" +Environment="ZAI_PASSWORD=yourpass" +Environment="SERVER_PORT=7300" +ExecStart=/path/to/z.ai2api_python/scripts/start.sh +PIDFile=/path/to/z.ai2api_python/server.pid + +[Install] +WantedBy=multi-user.target +``` + +Then: +```bash +sudo systemctl enable z-ai2api +sudo systemctl start z-ai2api +``` + +--- + +## Contributing + +When modifying scripts: +1. Test with `bash -n script.sh` (syntax check) +2. Test with `shellcheck script.sh` (linting) +3. Test all exit codes +4. Update this README + +--- + +## Support + +- **Repository:** https://github.com/Zeeeepa/z.ai2api_python +- **Issues:** https://github.com/Zeeeepa/z.ai2api_python/issues + +--- + +**Made with โค๏ธ for simplified Z.AI proxy deployment** diff --git a/scripts/all.sh b/scripts/all.sh new file mode 100755 index 0000000..159132b --- /dev/null +++ b/scripts/all.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +# all.sh - Run complete deployment, start server, and test + +set -e # Exit on any error + +# Color codes for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo -e "${BLUE}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${NC}" +echo -e "${BLUE}โ•‘ Z.AI to OpenAI API Proxy - Full Setup โ•‘${NC}" +echo -e "${BLUE}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" +echo "" + +# Trap errors +trap 'echo -e "${RED}โŒ Setup failed at step: $CURRENT_STEP${NC}"; exit 1' ERR + +# Check if we're in the correct directory +if [[ ! -f "main.py" ]]; then + echo -e "${RED}โŒ Error: main.py not found. Please run from project root.${NC}" + exit 1 +fi + +# Display environment +echo -e "${YELLOW}๐Ÿ“‹ Environment:${NC}" +echo " PWD: $(pwd)" +echo " Python: $(command -v python3 || echo 'not found')" +echo " uv: $(command -v uv || echo 'not found')" + +if [[ -n "$ZAI_EMAIL" ]]; then + echo " ZAI_EMAIL: $ZAI_EMAIL" +else + echo " ZAI_EMAIL: (not set - will use anonymous mode)" +fi + +if [[ -n "$ZAI_PASSWORD" ]]; then + echo " ZAI_PASSWORD: ***" +else + echo " ZAI_PASSWORD: (not set - will use anonymous mode)" +fi + +echo " SERVER_PORT: ${SERVER_PORT:-7300 (default)}" +echo "" + +# Step 1: Deploy +CURRENT_STEP="deploy" +echo -e "${GREEN}โ”โ”โ” Step 1/3: Deployment โ”โ”โ”${NC}" +bash scripts/deploy.sh +echo "" + +# Step 2: Start server +CURRENT_STEP="start server" +echo -e "${GREEN}โ”โ”โ” Step 2/3: Starting Server โ”โ”โ”${NC}" +bash scripts/start.sh +echo "" + +# Give server extra time to stabilize +sleep 2 + +# Step 3: Test API +CURRENT_STEP="test API" +echo -e "${GREEN}โ”โ”โ” Step 3/3: Testing API โ”โ”โ”${NC}" +bash scripts/send_openai_request.sh +echo "" + +# Success! +echo -e "${GREEN}โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—${NC}" +echo -e "${GREEN}โ•‘ โœ… Setup Complete! โ•‘${NC}" +echo -e "${GREEN}โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•${NC}" +echo "" +echo -e "${BLUE}๐Ÿ“Š Server Information:${NC}" + +if [[ -f "server.port" ]]; then + PORT=$(cat server.port) + echo " URL: http://localhost:$PORT" + echo " API: http://localhost:$PORT/v1" +fi + +if [[ -f "server.pid" ]]; then + PID=$(cat server.pid) + echo " PID: $PID" +fi + +echo "" +echo -e "${YELLOW}๐Ÿ’ก Useful Commands:${NC}" +echo " View logs: tail -f server.log" +echo " Stop server: kill \$(cat server.pid)" +echo " Restart: bash scripts/start.sh" +echo " Test API: bash scripts/send_openai_request.sh" +echo "" +echo -e "${GREEN}๐ŸŽ‰ Your OpenAI-compatible API proxy is ready!${NC}" + diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100755 index 0000000..13d7c52 --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# deploy.sh - Install dependencies and setup virtual environment + +set -e # Exit on any error + +echo "๐Ÿš€ Starting deployment of z.ai2api_python..." + +# Check if uv is installed +if ! command -v uv &> /dev/null; then + echo "โŒ Error: 'uv' is not installed." + echo "๐Ÿ“ฆ Install it with: curl -LsSf https://astral.sh/uv/install.sh | sh" + exit 2 +fi + +echo "โœ… uv found: $(uv --version)" + +# Check for required files +if [[ ! -f "main.py" ]]; then + echo "โŒ Error: main.py not found. Are you in the project root?" + exit 1 +fi + +if [[ ! -f "pyproject.toml" ]]; then + echo "โŒ Error: pyproject.toml not found. Are you in the project root?" + exit 1 +fi + +# Create/sync virtual environment +echo "๐Ÿ“ฆ Creating virtual environment and syncing dependencies..." +uv venv + +echo "๐Ÿ“ฅ Installing project dependencies..." +uv sync + +# Install OpenAI client for testing +echo "๐Ÿ”ง Installing OpenAI client for API testing..." +uv pip install "openai>=1.0.0,<2" + +echo "" +echo "โœ… Deployment complete!" +echo "๐Ÿ“ Virtual environment: .venv/" +echo "๐Ÿ Python: $(./.venv/bin/python --version)" +echo "" +echo "Next steps:" +echo " 1. Export credentials: export ZAI_EMAIL='your@email.com' ZAI_PASSWORD='yourpass'" +echo " 2. Start server: bash scripts/start.sh" +echo " 3. Or run all: bash scripts/all.sh" + diff --git a/scripts/send_openai_request.sh b/scripts/send_openai_request.sh new file mode 100755 index 0000000..70e2197 --- /dev/null +++ b/scripts/send_openai_request.sh @@ -0,0 +1,94 @@ +#!/usr/bin/env bash +# send_openai_request.sh - Send test OpenAI API request to the server + +set -e + +echo "๐Ÿงช Sending OpenAI API test request..." + +# Check if virtual environment exists +if [[ ! -d ".venv" ]]; then + echo "โŒ Error: Virtual environment not found. Run: bash scripts/deploy.sh" + exit 1 +fi + +# Get server port +if [[ -f "server.port" ]]; then + SERVER_PORT=$(cat server.port) +else + SERVER_PORT=${SERVER_PORT:-7300} + echo "โš ๏ธ server.port not found, using SERVER_PORT=${SERVER_PORT}" +fi + +# Check if server is running +if [[ -f "server.pid" ]]; then + SERVER_PID=$(cat server.pid) + if ! ps -p $SERVER_PID > /dev/null 2>&1; then + echo "โŒ Error: Server process (PID: $SERVER_PID) is not running" + exit 4 + fi +else + echo "โš ๏ธ server.pid not found, cannot verify server is running" +fi + +# Get AUTH_TOKEN +AUTH_TOKEN=${AUTH_TOKEN:-"sk-any"} + +echo "๐Ÿ“ก Request details:" +echo " URL: http://localhost:$SERVER_PORT/v1" +echo " Model: gpt-5" +echo " AUTH_TOKEN: ${AUTH_TOKEN:0:8}... (masked for security)" +echo "" + +# Create and run test script +echo "๐Ÿ”„ Executing request..." +PYTHONPATH= ./.venv/bin/python - < /dev/null; then + lsof -ti:$port &> /dev/null + elif command -v nc &> /dev/null; then + nc -z localhost $port &> /dev/null + else + # Fallback: try to bind with Python + # If bind succeeds, port is FREE (return 1), if it fails, port is IN USE (return 0) + if ./.venv/bin/python -c "import socket; s=socket.socket(); s.bind(('', $port)); s.close()" 2>/dev/null; then + return 1 # Port is free + else + return 0 # Port is in use + fi + fi +} + +# Find available port starting from SERVER_PORT (default 7300) +START_PORT=${SERVER_PORT:-7300} +MAX_ATTEMPTS=10 +SELECTED_PORT="" + +echo "๐Ÿ” Searching for available port starting from $START_PORT..." + +for ((i=0; i<$MAX_ATTEMPTS; i++)); do + TEST_PORT=$((START_PORT + i)) + if ! is_port_in_use $TEST_PORT; then + SELECTED_PORT=$TEST_PORT + echo "โœ… Found available port: $SELECTED_PORT" + break + else + echo " Port $TEST_PORT is busy, trying next..." + fi +done + +if [[ -z "$SELECTED_PORT" ]]; then + echo "โŒ Error: Could not find available port after $MAX_ATTEMPTS attempts" + echo " Tried ports: $START_PORT-$((START_PORT + MAX_ATTEMPTS - 1))" + exit 3 +fi + +# Set environment variables +export LISTEN_PORT=$SELECTED_PORT +export PYTHONPATH= +export AUTH_TOKEN=${AUTH_TOKEN:-"sk-any"} + +# Optional: Use ZAI credentials if provided +if [[ -n "$ZAI_EMAIL" && -n "$ZAI_PASSWORD" ]]; then + echo "๐Ÿ” Using ZAI credentials: $ZAI_EMAIL" + export ZAI_EMAIL + export ZAI_PASSWORD +else + echo "โš ๏ธ ZAI_EMAIL and ZAI_PASSWORD not set - running in anonymous mode" +fi + +# Clean up old logs and PID files +rm -f server.log server.pid + +# Start server in background +echo "๐Ÿš€ Starting server on port $SELECTED_PORT..." +nohup ./.venv/bin/python main.py > server.log 2>&1 & +SERVER_PID=$! + +# Save PID and port +echo $SERVER_PID > server.pid +echo $SELECTED_PORT > server.port + +echo "โœ… Server started!" +echo " PID: $SERVER_PID" +echo " Port: $SELECTED_PORT" +echo " Logs: server.log" + +# Wait for server to be ready +echo "โณ Waiting for server to be ready..." +MAX_WAIT=15 +for ((i=1; i<=$MAX_WAIT; i++)); do + if is_port_in_use $SELECTED_PORT; then + echo "โœ… Server is ready after ${i}s!" + echo "" + echo "๐Ÿ“Š Server Info:" + echo " Base URL: http://localhost:$SELECTED_PORT" + echo " API URL: http://localhost:$SELECTED_PORT/v1" + echo " AUTH_TOKEN: $AUTH_TOKEN" + echo "" + echo "To stop server: kill $SERVER_PID" + echo "To view logs: tail -f server.log" + exit 0 + fi + sleep 1 +done + +echo "โŒ Error: Server failed to start within ${MAX_WAIT}s" +echo "๐Ÿ“‹ Last 20 lines of server.log:" +tail -20 server.log +exit 4