Skip to content
Merged
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ services:

localaik is a plain HTTP server, so any language or SDK that can set a base URL will work.

More runnable samples (curl, Go, Python, JavaScript, Java) live under **[examples/](examples/README.md)**.

### Gemini SDK

**Go:**
Expand Down
42 changes: 42 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Examples

Small, runnable samples that talk to **localaik** on `http://localhost:8090`. Use them to sanity-check your setup or as templates for your own code.

## Prerequisites

1. Start localaik (pick one):

```bash
docker run -d -p 8090:8090 gokhalh/localaik
```

Or from the repo root: `make docker-up` (defaults to port `18090` — set `PORT=8090` if you want the examples unchanged).

2. Wait until the model is loaded (`GET /health` returns 200). The first start can take a while.

3. Run an example from the directory listed below (each folder has its own dependencies).

**Python 3**

- The **[python/](python/)** samples need **Python 3** and the listed SDK packages (`google-genai`, OpenAI client, etc.).
- The **[curl/](curl/)** scripts are shell + `curl`, but they pipe the response through **`python3 -m json.tool`** so the JSON is pretty-printed. Install **Python 3** on your PATH, or remove the `| python3 -m json.tool` suffix and read raw JSON instead.

## Layout

| Language | Gemini | OpenAI | Structured output (Gemini) |
| ----------- | ------ | ------ | --------------------------- |
| **curl** | [curl/gemini.sh](curl/gemini.sh) | [curl/openai.sh](curl/openai.sh) | [curl/gemini-structured.sh](curl/gemini-structured.sh) |
| **Go** | [go/gemini](go/gemini/main.go) | [go/openai](go/openai/main.go) | [go/gemini-structured](go/gemini-structured/main.go) |
| **Python** | [python/gemini](python/gemini/main.py) | [python/openai](python/openai/main.py) | [python/gemini-structured](python/gemini-structured/main.py) |
| **JavaScript** | [javascript/gemini](javascript/gemini/index.mjs) | [javascript/openai](javascript/openai/index.mjs) | [javascript/gemini-structured](javascript/gemini-structured/index.mjs) |
| **Java** | [java/gemini](java/gemini/Gemini.java) | [java/openai](java/openai/OpenAI.java) | [java/gemini-structured](java/gemini-structured/GeminiStructured.java) |

## Conventions

- **Base URL:** `http://localhost:8090` for Gemini-style calls; OpenAI clients use `http://localhost:8090/v1`.
- **API key:** Examples use a placeholder such as `test` where the SDK requires one; localaik does not validate keys.
- **Model name:** Samples use `localaik` as the model id where applicable; the proxy forwards to the bundled upstream model.

## Dependencies

Examples do not share a single lockfile. Install what you need per language (e.g. `google-genai` for Python, `google.golang.org/genai` for Go, official OpenAI packages for OpenAI examples). **curl-only:** aside from optional `python3` for JSON formatting (see above), no extra installs.
26 changes: 26 additions & 0 deletions examples/curl/gemini-structured.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh
curl -s http://localhost:8090/v1beta/models/localaik:generateContent \
-H "Content-Type: application/json" \
-d '{
"contents": [
{
"role": "user",
"parts": [{ "text": "List three popular programming languages with their year of creation and primary use case." }]
}
],
"generationConfig": {
"responseMimeType": "application/json",
"responseSchema": {
"type": "ARRAY",
"items": {
"type": "OBJECT",
"properties": {
"name": { "type": "STRING" },
"year": { "type": "INTEGER" },
"use_case": { "type": "STRING" }
},
"required": ["name", "year", "use_case"]
}
}
}
}' | python3 -m json.tool
11 changes: 11 additions & 0 deletions examples/curl/gemini.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh
curl -s http://localhost:8090/v1beta/models/localaik:generateContent \
-H "Content-Type: application/json" \
-d '{
"contents": [
{
"role": "user",
"parts": [{ "text": "What are three interesting facts about the Go programming language?" }]
}
]
}' | python3 -m json.tool
10 changes: 10 additions & 0 deletions examples/curl/openai.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh
curl -s http://localhost:8090/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "localaik",
"messages": [
{ "role": "system", "content": "You are a helpful assistant. Keep answers concise." },
{ "role": "user", "content": "What is the capital of France and what is it known for?" }
]
}' | python3 -m json.tool
49 changes: 49 additions & 0 deletions examples/go/gemini-structured/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package main

import (
"context"
"fmt"
"log"

"google.golang.org/genai"
)

func main() {
ctx := context.Background()

client, err := genai.NewClient(ctx, &genai.ClientConfig{
APIKey: "test",
Backend: genai.BackendGeminiAPI,
HTTPOptions: genai.HTTPOptions{
BaseURL: "http://localhost:8090",
},
})
if err != nil {
log.Fatal(err)
}

resp, err := client.Models.GenerateContent(ctx,
"localaik",
genai.Text("List three popular programming languages with their year of creation and primary use case."),
&genai.GenerateContentConfig{
ResponseMIMEType: "application/json",
ResponseSchema: &genai.Schema{
Type: genai.TypeArray,
Items: &genai.Schema{
Type: genai.TypeObject,
Properties: map[string]*genai.Schema{
"name": {Type: genai.TypeString},
"year": {Type: genai.TypeInteger},
"use_case": {Type: genai.TypeString},
},
Required: []string{"name", "year", "use_case"},
},
},
},
)
if err != nil {
log.Fatal(err)
}

fmt.Println(resp.Text())
}
35 changes: 35 additions & 0 deletions examples/go/gemini/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package main

import (
"context"
"fmt"
"log"

"google.golang.org/genai"
)

func main() {
ctx := context.Background()

client, err := genai.NewClient(ctx, &genai.ClientConfig{
APIKey: "test",
Backend: genai.BackendGeminiAPI,
HTTPOptions: genai.HTTPOptions{
BaseURL: "http://localhost:8090",
},
})
if err != nil {
log.Fatal(err)
}

resp, err := client.Models.GenerateContent(ctx,
"localaik",
genai.Text("What are three interesting facts about the Go programming language?"),
nil,
)
if err != nil {
log.Fatal(err)
}

fmt.Println(resp.Text())
}
32 changes: 32 additions & 0 deletions examples/go/openai/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"context"
"fmt"
"log"

"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/option"
)

func main() {
ctx := context.Background()

client := openai.NewClient(
option.WithAPIKey("test"),
option.WithBaseURL("http://localhost:8090/v1/"),
)

resp, err := client.Chat.Completions.New(ctx, openai.ChatCompletionNewParams{
Model: "localaik",
Messages: []openai.ChatCompletionMessageParamUnion{
openai.SystemMessage("You are a helpful assistant. Keep answers concise."),
openai.UserMessage("What is the capital of France and what is it known for?"),
},
})
if err != nil {
log.Fatal(err)
}

fmt.Println(resp.Choices[0].Message.Content)
}
39 changes: 39 additions & 0 deletions examples/java/gemini-structured/GeminiStructured.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import com.google.genai.Client;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.Schema;
import java.util.List;
import java.util.Map;

public class GeminiStructured {
public static void main(String[] args) throws Exception {
Client client = Client.builder()
.apiKey("test")
.baseUrl("http://localhost:8090")
.build();

Schema itemSchema = Schema.builder()
.type("OBJECT")
.properties(Map.of(
"name", Schema.builder().type("STRING").build(),
"year", Schema.builder().type("INTEGER").build(),
"use_case", Schema.builder().type("STRING").build()))
.required(List.of("name", "year", "use_case"))
.build();

GenerateContentConfig config = GenerateContentConfig.builder()
.responseMimeType("application/json")
.responseSchema(Schema.builder()
.type("ARRAY")
.items(itemSchema)
.build())
.build();

GenerateContentResponse response = client.models.generateContent(
"localaik",
"List three popular programming languages with their year of creation and primary use case.",
config);

System.out.println(response.text());
}
}
18 changes: 18 additions & 0 deletions examples/java/gemini/Gemini.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import com.google.genai.Client;
import com.google.genai.types.GenerateContentResponse;

public class Gemini {
public static void main(String[] args) throws Exception {
Client client = Client.builder()
.apiKey("test")
.baseUrl("http://localhost:8090")
.build();

GenerateContentResponse response = client.models.generateContent(
"localaik",
"What are three interesting facts about the Go programming language?",
null);

System.out.println(response.text());
}
}
23 changes: 23 additions & 0 deletions examples/java/openai/OpenAI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.chat.completions.ChatCompletion;
import com.openai.models.chat.completions.ChatCompletionCreateParams;

public class OpenAI {
public static void main(String[] args) {
OpenAIClient client = OpenAIOkHttpClient.builder()
.apiKey("test")
.baseUrl("http://localhost:8090/v1/")
.build();

ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model("localaik")
.addSystemMessage("You are a helpful assistant. Keep answers concise.")
.addUserMessage("What is the capital of France and what is it known for?")
.build();

ChatCompletion completion = client.chat().completions().create(params);

System.out.println(completion.choices().get(0).message().content().orElse(""));
}
}
28 changes: 28 additions & 0 deletions examples/javascript/gemini-structured/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({
apiKey: "test",
httpOptions: { apiVersion: "v1beta", baseUrl: "http://localhost:8090" },
});

const response = await client.models.generateContent({
model: "localaik",
contents: "List three popular programming languages with their year of creation and primary use case.",
config: {
responseMimeType: "application/json",
responseSchema: {
type: "ARRAY",
items: {
type: "OBJECT",
properties: {
name: { type: "STRING" },
year: { type: "INTEGER" },
use_case: { type: "STRING" },
},
required: ["name", "year", "use_case"],
},
},
},
});

console.log(response.text);
13 changes: 13 additions & 0 deletions examples/javascript/gemini/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { GoogleGenAI } from "@google/genai";

const client = new GoogleGenAI({
apiKey: "test",
httpOptions: { apiVersion: "v1beta", baseUrl: "http://localhost:8090" },
});

const response = await client.models.generateContent({
model: "localaik",
contents: "What are three interesting facts about the Go programming language?",
});

console.log(response.text);
16 changes: 16 additions & 0 deletions examples/javascript/openai/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import OpenAI from "openai";

const client = new OpenAI({
apiKey: "test",
baseURL: "http://localhost:8090/v1",
});

const response = await client.chat.completions.create({
model: "localaik",
messages: [
{ role: "system", content: "You are a helpful assistant. Keep answers concise." },
{ role: "user", content: "What is the capital of France and what is it known for?" },
],
});

console.log(response.choices[0].message.content);
32 changes: 32 additions & 0 deletions examples/python/gemini-structured/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from google import genai
from google.genai import types

client = genai.Client(
api_key="test",
http_options=types.HttpOptions(
api_version="v1beta",
base_url="http://localhost:8090",
),
)

response = client.models.generate_content(
model="localaik",
contents="List three popular programming languages with their year of creation and primary use case.",
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=types.Schema(
type="ARRAY",
items=types.Schema(
type="OBJECT",
properties={
"name": types.Schema(type="STRING"),
"year": types.Schema(type="INTEGER"),
"use_case": types.Schema(type="STRING"),
},
required=["name", "year", "use_case"],
),
),
),
)

print(response.text)
Loading
Loading