Skip to content
Open
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
199 changes: 117 additions & 82 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,54 @@
# Gonka OpenAI Proxy

OpenAI-compatible API proxy for Gonka that provides ChatGPT-like interface with API key authentication.

👉 **Try it here:**
👉 https://gonka-gateway.mingles.ai/
OpenAI-compatible API proxy for Gonka that provides a ChatGPT-like interface with API key authentication. Self-hosted, no database required — configured entirely via environment variables.

## Features

- **OpenAI-compatible API**: Compatible with OpenAI Python SDK and other OpenAI-compatible clients
- **API Key Authentication**: Secure access using API keys (like ChatGPT API)
- **OpenAI-compatible API**: Drop-in replacement for OpenAI Python SDK and other OpenAI-compatible clients
- **API Key Authentication**: Secure access using configurable API keys
- **Streaming Support**: Supports both streaming and non-streaming responses
- **Tool Emulation**: Automatic prompt-based tool call emulation for models that don't support native tool calling
- **Circuit Breaker**: Prevents cascading failures when the Gonka backend is degraded
- **Retry with Backoff**: Automatic retry with exponential backoff on transient errors
- **Web Interface**: Built-in web chat interface for testing
- **Automatic Model Loading**: Loads available models from Gonka API on startup
- **Docker Support**: Ready-to-use Docker container

## Configuration
## Quick Start

Copy `.env.example` to `.env` and configure the following variables:
### Running Locally

1. Clone the repository:
```bash
# Gonka API Configuration
GONKA_PRIVATE_KEY=your_hex_private_key_here
GONKA_ADDRESS=your_gonka_address_bech32
GONKA_ENDPOINT=https://host:port/v1
GONKA_PROVIDER_ADDRESS=provider_gonka_address_bech32

# API Key for external access (like ChatGPT API)
API_KEY=sk-your-secret-api-key-here

# Server Configuration (optional)
HOST=0.0.0.0
PORT=8000
git clone https://github.com/MinglesAI/gonka-proxy.git
cd gonka-proxy
```

### Configuration Details

#### GONKA_PROVIDER_ADDRESS

**What is it?** `GONKA_PROVIDER_ADDRESS` is the provider (host) address in the Gonka network in bech32 format. It is used to sign requests to the Gonka API.

**Where to get it?**

1. **From provider documentation**: If you are using a specific Gonka provider, their address should be specified in their documentation or provider page.

2. **From endpoint metadata**: The provider address is usually associated with the endpoint (`GONKA_ENDPOINT`). The provider should specify their Gonka address in the documentation or during registration.
2. Install dependencies:
```bash
pip install -r requirements.txt
```

3. **Via Gonka Dashboard**: If you have access to the Gonka Dashboard, the provider address can be found in your connection information or node settings.
3. Create a `.env` file (see [Environment Variables](#environment-variables)):
```bash
cp .env.example .env
# Edit .env with your values
```

4. **Contact the provider**: If you are using a public Gonka endpoint, contact the endpoint owner or Gonka support to get the provider address.
4. Run the server:
```bash
python -m app.main
```

**Example**: The address usually looks like `gonka1...` (bech32 format), e.g., `gonka1abc123def456...`
Or with uvicorn directly:
```bash
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
```

**Important**: The provider address is used in the cryptographic signature of each request, so it must be correct for successful authentication.
5. Open `http://localhost:8000/` in your browser to use the web chat interface.

## Running with Docker
### Running with Docker

1. Build the Docker image:
1. Build the image:
```bash
docker build -t gonka-proxy .
```
Expand All @@ -65,36 +58,80 @@ docker build -t gonka-proxy .
docker run -d \
--name gonka-proxy \
-p 8000:8000 \
--env-file .env \
-e GONKA_PRIVATE_KEY=your_hex_private_key \
-e GONKA_ADDRESS=your_gonka_address_bech32 \
-e GONKA_ENDPOINT=https://host:port/v1 \
-e GONKA_PROVIDER_ADDRESS=provider_gonka_address_bech32 \
-e API_KEY=sk-your-secret-api-key \
gonka-proxy
```

## Running Locally

1. Install dependencies:
Or with a `.env` file:
```bash
pip install -r requirements.txt
docker run -d \
--name gonka-proxy \
-p 8000:8000 \
--env-file .env \
gonka-proxy
```

2. Set environment variables or create `.env` file
## Environment Variables

3. Run the server:
```bash
python -m app.main
| Variable | Required | Default | Description |
|---|---|---|---|
| `GONKA_PRIVATE_KEY` | ✅ | — | Your ECDSA private key in hex format (with or without `0x` prefix) |
| `GONKA_ADDRESS` | ✅ | — | Your Gonka address in bech32 format (e.g. `gonka1abc...`) |
| `GONKA_ENDPOINT` | ✅ | — | Gonka API base URL (e.g. `https://host:port/v1`) |
| `GONKA_PROVIDER_ADDRESS` | ✅ | — | Provider's Gonka address in bech32 format — used for request signing |
| `API_KEY` | ✅ | — | Secret key clients must send in the `Authorization` header |
| `HOST` | ❌ | `0.0.0.0` | Server bind address |
| `PORT` | ❌ | `8000` | Server port |
| `GONKA_STREAM_READ_TIMEOUT` | ❌ | `300.0` | Max seconds to wait for streaming data from backend |

### Configuration Details

#### GONKA_PRIVATE_KEY
Your ECDSA private key in hex format. Used to sign every request to the Gonka backend.
Example: `a1b2c3d4e5f6...` or `0xa1b2c3d4e5f6...`

#### GONKA_ADDRESS
Your address in the Gonka network (bech32 format). Sent as the `X-Requester-Address` header.
Example: `gonka1qyqszqgpqyqszqgpqyqszqgp...`

#### GONKA_ENDPOINT
The Gonka inference API endpoint. Must include the `/v1` path segment.
Example: `https://my-gonka-node.example.com/v1`

#### GONKA_PROVIDER_ADDRESS
The **provider's** Gonka address (bech32 format). This is included in the cryptographic signature of every request and must match what the provider expects. Obtain this from your Gonka provider's documentation or contact page.
Example: `gonka1provideraddress...`

#### API_KEY
The bearer token clients must include in requests to the proxy.
Example: `sk-my-secret-key-123`

Clients send it as:
```
Authorization: Bearer sk-my-secret-key-123
```

Or with uvicorn directly:
### Example `.env` file

```bash
uvicorn app.main:app --host 0.0.0.0 --port 8000
GONKA_PRIVATE_KEY=0xaabbccddeeff...
GONKA_ADDRESS=gonka1youraddress...
GONKA_ENDPOINT=https://my-gonka-node.example.com/v1
GONKA_PROVIDER_ADDRESS=gonka1provideraddress...
API_KEY=sk-my-secret-api-key
```

## Usage

### Web Interface

Access the web interface at `http://localhost:8000/` to test the API interactively.
Open `http://localhost:8000/` to access the built-in chat interface.

### Using OpenAI Python SDK
### OpenAI Python SDK

```python
from openai import OpenAI
Expand All @@ -114,20 +151,6 @@ response = client.chat.completions.create(
print(response.choices[0].message.content)
```

### Using curl

```bash
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-secret-key" \
-d '{
"model": "gonka-model",
"messages": [
{"role": "user", "content": "Hello!"}
]
}'
```

### Streaming

```python
Expand All @@ -140,9 +163,7 @@ client = OpenAI(

stream = client.chat.completions.create(
model="gonka-model",
messages=[
{"role": "user", "content": "Tell me a story"}
],
messages=[{"role": "user", "content": "Tell me a story"}],
stream=True
)

Expand All @@ -151,27 +172,41 @@ for chunk in stream:
print(chunk.choices[0].delta.content, end="")
```

### curl

```bash
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-your-secret-key" \
-d '{
"model": "gonka-model",
"messages": [{"role": "user", "content": "Hello!"}]
}'
```

## API Endpoints

- `POST /v1/chat/completions` - Chat completions (OpenAI-compatible)
- `GET /v1/models` - List available models
- `GET /api/models` - Get available models (no auth, for web interface)
- `GET /health` - Health check endpoint (no auth required)
- `GET /` - Web chat interface
| Endpoint | Auth | Description |
|---|---|---|
| `POST /v1/chat/completions` | ✅ | Chat completions (OpenAI-compatible) |
| `GET /v1/models` | ✅ | List available models (OpenAI-compatible) |
| `GET /api/models` | ❌ | Get available models (for web interface) |
| `GET /health` | ❌ | Health check (includes circuit breaker state) |
| `GET /` | ❌ | Web chat interface |

## Authentication
## Architecture

All endpoints except `/health`, `/api/models`, and `/` require authentication using the `Authorization` header:
### Tool Emulation

```
Authorization: Bearer sk-your-secret-key
```
If the Gonka model doesn't support native tool calling (`tools` + `tool_choice`), the proxy automatically converts tool definitions into a system prompt and parses tool call JSON from the model's text response. This is transparent to the client — it still receives standard OpenAI-format `tool_calls` in the response.

Or simply:
### Circuit Breaker

```
Authorization: sk-your-secret-key
```
Wraps non-streaming Gonka backend calls. After 5 consecutive failures, the circuit opens and requests are rejected immediately with a `503` error for 60 seconds, then transitions to half-open to test recovery.

### Retry

Non-streaming requests are retried up to 2 times with exponential backoff on transient errors.

## License

Expand Down
Loading