Skip to main content

OpenAI client with Gonka network integration

Project description

Gonka OpenAI for Python

A Python library for using OpenAI's API through the Gonka network.

Installation

pip install gonka-openai
# or
poetry add gonka-openai

Usage

There are two ways to use this library:

Option 1: Using the GonkaOpenAI wrapper (recommended)

from gonka_openai import GonkaOpenAI

# Private key can be provided directly or through environment variable GONKA_PRIVATE_KEY
client = GonkaOpenAI(
    api_key="mock-api-key",  # OpenAI requires any key, defaults to "mock-api-key" if not provided
    gonka_private_key="0x1234...",  # ECDSA private key for signing requests
    source_url="https://api.gonka.testnet.example.com",  # Resolve endpoints from this SourceUrl
    # Optional parameters:
    # http_client=custom_client,  # Optional custom HTTP client
)

# Use exactly like the original OpenAI client
response = client.chat.completions.create(
    model="Qwen/QwQ-32B",
    messages=[{"role": "user", "content": "Hello! Tell me a short joke."}],
)

Option 2: Using the original OpenAI client with a custom HTTP client

from openai import OpenAI
from gonka_openai import gonka_http_client, resolve_and_select_endpoint

source_url = "https://api.gonka.testnet.example.com"
endpoints, selected = resolve_and_select_endpoint(source_url=source_url)

# Create a custom HTTP client for Gonka with your private key
http_client = gonka_http_client(
    private_key="0x1234...",  # Your private key
    transfer_address=selected.address  # Provider address from the endpoint
    # Optional parameters:
    # http_client=custom_client,  # Optional custom HTTP client
)

# Create an OpenAI client with the custom HTTP client
client = OpenAI(
    api_key="mock-api-key",  # OpenAI requires any key
    base_url=selected.url,  # Use the URL from the endpoint
    http_client=http_client  # Use the custom HTTP client that signs requests
)

# Use normally - all requests will be dynamically signed and routed through Gonka
response = client.chat.completions.create(
    model="Qwen/QwQ-32B",
    messages=[{"role": "user", "content": "What is the capital of France?"}],
)

This approach provides the same dynamic request signing as Option 1, but gives you more direct control over the OpenAI client configuration.

Environment Variables

Instead of passing configuration directly, you can use environment variables:

  • GONKA_PRIVATE_KEY: Your ECDSA private key for signing requests
  • GONKA_SOURCE_URL: URL to fetch participants with proof and resolve endpoints (e.g., "https://gonka1.example.com")
  • GONKA_VERIFY_PROOF: (Optional) Set to 1 to enable ICS23 proof verification during endpoint discovery. If unset, verification is skipped by default.
  • GONKA_ADDRESS: (Optional) Override the derived gonka address
  • GONKA_ENDPOINTS: (Optional) Comma-separated list of Gonka network endpoints in the format "url;address" where address is the provider's gonka address (e.g., "https://gonka1.example.com;gonka1address"). Each endpoint MUST include a provider address.

Example with environment variables:

# Set in your environment:
# GONKA_PRIVATE_KEY=0x1234...
# GONKA_SOURCE_URL=https://gonka1.example.com

from gonka_openai import GonkaOpenAI

client = GonkaOpenAI(
    api_key="mock-api-key",
    # No need to provide endpoints, SourceUrl will be read from environment
)

# Use normally
response = client.chat.completions.create(
    model="Qwen/QwQ-32B",
    messages=[{"role": "user", "content": "Hello!"}],
)

Advanced Configuration

Custom Endpoint Selection

You can provide a custom endpoint selection strategy:

from gonka_openai import GonkaOpenAI
from gonka_openai.utils import Endpoint

# Create endpoints directly
endpoints = [
    Endpoint(url="https://api.gonka.testnet.example.com", address="gonka1transferaddress"),
    Endpoint(url="https://api2.gonka.testnet.example.com", address="gonka2transferaddress")
]

def first_endpoint_strategy(endpoints):
    """Always select the first endpoint."""
    return endpoints[0]

client = GonkaOpenAI(
    api_key="mock-api-key",
    gonka_private_key="0x1234...",
    endpoints=endpoints,
    endpoint_selection_strategy=first_endpoint_strategy
)

# Use normally
response = client.chat.completions.create(
    model="Qwen/QwQ-32B",
    messages=[{"role": "user", "content": "Hello! Tell me a short joke."}],
)

How It Works

  1. Custom HTTP Client: The library intercepts all outgoing API requests by wrapping the HTTP client's request method
  2. Request Body Signing: For each request, the library:
    • Extracts the request body
    • Generates a hybrid timestamp in nanoseconds (required for all requests)
      • Uses a combination of wall clock time and performance counter
      • Ensures timestamps are unique and monotonically increasing
      • Maintains accuracy to standard time servers within at least 30 seconds
    • Concatenates the request body, timestamp, and provider address
    • Signs the concatenated data with your private key using ECDSA
    • Adds the signature to the Authorization header
  3. Headers: The library adds the following headers to each request:
    • X-Requester-Address: Your gonka address (derived from your private key)
    • X-Timestamp: The timestamp in nanoseconds used for signing (required for all requests)
  4. Endpoint Selection: Requests are routed to the Gonka network using a randomly selected endpoint
  5. Provider Address: Each endpoint MUST include a provider address (the gonka address of the provider at that endpoint). This is a required parameter for all requests and will cause requests to fail if not provided.

Cryptographic Implementation

The library implements:

  1. ECDSA Signatures: Using Secp256k1 curve to sign request bodies with the private key
  2. Gonka Address Generation: Deriving gonka-compatible addresses from private keys using standard bech32 encoding

Participants with proof (standalone)

from gonka_openai import get_participants_with_proof

# Fetch participants from a base URL for an epoch (e.g., "current")
endpoints = get_participants_with_proof(
    base_url="http://localhost:9000",
    epoch="current",
)

for e in endpoints:
    print(e.url, e.address)
  1. Dynamic Request Signing: Using a custom HTTP client implementation to intercept and sign each request before it's sent

Limitations

The current implementation has a few limitations:

  1. Installation Requirements: The secp256k1 package requires C dependencies to be installed on your system
  2. Body Extraction: Some complex body types may use simplified representations for signing
  3. Error Handling: Error handling is basic and could be improved in future versions
  4. Testing: Comprehensive testing is recommended before using in production

Dependencies

  • openai: Official OpenAI Python client
  • secp256k1: For ECDSA signature generation
  • bech32: For gonka address encoding
  • python-dotenv: For environment variable loading

Building from Source

git clone https://github.com/yourusername/gonka-openai.git
cd gonka-openai/python
pip install -e .

Testing

To run a simple test that demonstrates the client:

cd python
python test.py

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gonka_openai-0.2.6.tar.gz (18.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gonka_openai-0.2.6-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file gonka_openai-0.2.6.tar.gz.

File metadata

  • Download URL: gonka_openai-0.2.6.tar.gz
  • Upload date:
  • Size: 18.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.13

File hashes

Hashes for gonka_openai-0.2.6.tar.gz
Algorithm Hash digest
SHA256 fdaca9f12d317673af63f42d35c08cc980b2bb121aadabff9bea31e9adbcac28
MD5 bf22797ceb887d3d901c4fcbf95b4de5
BLAKE2b-256 15efcfab457f4f62e55b213a9f6259414e103a25a11063e4ff5871260e89e64d

See more details on using hashes here.

File details

Details for the file gonka_openai-0.2.6-py3-none-any.whl.

File metadata

  • Download URL: gonka_openai-0.2.6-py3-none-any.whl
  • Upload date:
  • Size: 18.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.9.13

File hashes

Hashes for gonka_openai-0.2.6-py3-none-any.whl
Algorithm Hash digest
SHA256 8db263b912aba192a7da162825608554acde21ea5fb8a3c0e852488b4357e8b1
MD5 c5252d1242ac01e74b6e49d625368154
BLAKE2b-256 ed858554b3973715f99cdf47d64bb3529eb479fd44012191445b113f42ff2f5c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page