A deterministic OpenAI API emulator for testing and CI/CD pipelines. Provides scripted responses that make official OpenAI client libraries "just work" without actual API calls.
- Full SDK Compatibility: Works with official OpenAI Python and JavaScript SDKs
- Simple API: Just send text, get text back - no complex matching rules
- Deterministic Responses: Script exact responses for reproducible testing
- Streaming Support: Full SSE streaming for chat completions and responses
- Session Isolation: Token-based session management for concurrent tests
- Pattern Matching: Optional regex patterns for dynamic responses
- Kubernetes Ready: Health checks, Docker support, and K8s manifests included
# Build and run
make run
# Or directly with Go
go run cmd/openai-emulator/main.go# Build and run container
make docker-run
# Or manually
docker build -t openai-emulator .
docker run -p 8080:8080 openai-emulator# Run all tests (Go unit tests + conformance)
make test
# Run only conformance tests
make conformance
# Run tests against Docker container
make docker-testGET /v1/models- List modelsGET /v1/models/{id}- Get model detailsPOST /v1/responses- Text completions (streaming/non-streaming)POST /v1/chat/completions- Chat completions (streaming/non-streaming)
POST /_emulator/script- Load test scriptsPOST /_emulator/reset- Reset session stateGET /_emulator/state- Debug state (requires DEBUG=true)
GET /healthz- Liveness probeGET /readyz- Readiness probe
from openai import OpenAI
client = OpenAI(
api_key="test-token",
base_url="http://localhost:8080/v1"
)
# Use normally
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello"}]
)import OpenAI from 'openai';
const openai = new OpenAI({
apiKey: 'test-token',
baseURL: 'http://localhost:8080/v1'
});
// Use normally
const response = await openai.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: 'Hello' }]
});Load scripts via POST /_emulator/script:
curl -X POST http://localhost:8080/_emulator/script \
-H "Authorization: Bearer test-token" \
-H "Content-Type: application/json" \
-d '{"reset": true, "responses": "Hello from the emulator!"}'curl -X POST http://localhost:8080/_emulator/script \
-H "Authorization: Bearer test-token" \
-H "Content-Type: application/json" \
-d '{
"reset": true,
"responses": [
"First response",
"Second response",
"Third response"
]
}'curl -X POST http://localhost:8080/_emulator/script \
-H "Authorization: Bearer test-token" \
-H "Content-Type: application/json" \
-d '{
"reset": true,
"responses": {
".*hello.*": "Hi there!",
".*help.*": "How can I help you?",
".*weather.*": "It's sunny today!"
}
}'# Apply manifests
kubectl apply -f k8s/
# Or use with your own image
kubectl set image deployment/openai-emulator openai-emulator=your-registry/openai-emulator:tagPORT- Server port (default: 8080)DEBUG- Enable debug endpoints (default: false)EMULATOR_URL- URL for conformance tests (default: http://localhost:8080)
See CLAUDE.md for detailed development documentation.
This emulator prioritizes:
- SDK Compatibility: Real OpenAI SDKs must work without modification
- Simplicity: Send text, get text back - no complex configuration
- Deterministic Behavior: Scripted responses for reproducible tests
- Streaming Fidelity: Accurate SSE streaming implementation
- Automatic Error Handling: Invalid models return proper OpenAI errors
Apache 2.0