add Python example with openai==2.3.0 (latest) and dependency pinning standards to CLAUDE.md
This commit is contained in:
parent
973c045af6
commit
39502bcac3
7 changed files with 320 additions and 0 deletions
28
CLAUDE.md
28
CLAUDE.md
|
|
@ -166,8 +166,36 @@ Each language's index.html should:
|
||||||
- ✅ EXPLAIN the specific API integration
|
- ✅ EXPLAIN the specific API integration
|
||||||
- ✅ DOCUMENT our specific implementation choices
|
- ✅ DOCUMENT our specific implementation choices
|
||||||
- ✅ PROVIDE troubleshooting for this language
|
- ✅ PROVIDE troubleshooting for this language
|
||||||
|
- ✅ ALWAYS pin to LATEST version of dependencies (check pip/npm/etc for current version)
|
||||||
- ❌ NO general programming tutorials
|
- ❌ NO general programming tutorials
|
||||||
- ❌ NO "What is programming?" sections
|
- ❌ NO "What is programming?" sections
|
||||||
|
- ❌ NO lazy unpinned dependencies (>=1.0.0 is WRONG - use ==2.3.0)
|
||||||
|
- ❌ NO old versions - always check latest before pinning
|
||||||
|
|
||||||
|
## Dependency Version Standards
|
||||||
|
**CRITICAL: Always pin to the LATEST specific version**
|
||||||
|
|
||||||
|
Before adding any dependency:
|
||||||
|
1. Check the latest version: `pip index versions openai` or `npm view openai version`
|
||||||
|
2. Pin to that EXACT version: `openai==2.3.0` (NOT `openai>=1.0.0`)
|
||||||
|
3. Document the version check date in a comment
|
||||||
|
4. Update regularly - check versions every few weeks
|
||||||
|
|
||||||
|
**Examples of CORRECT pinning:**
|
||||||
|
```
|
||||||
|
# Python (checked 2025-10-12)
|
||||||
|
openai==2.3.0
|
||||||
|
|
||||||
|
# Node.js (checked 2025-10-12)
|
||||||
|
"openai": "4.67.3"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples of LAZY/WRONG pinning:**
|
||||||
|
```
|
||||||
|
❌ openai>=1.0.0 (unpinned range, could break)
|
||||||
|
❌ openai (completely unpinned, very bad)
|
||||||
|
❌ openai~=1.0 (lazy, not latest)
|
||||||
|
```
|
||||||
|
|
||||||
## Makefile Commands for Language Examples
|
## Makefile Commands for Language Examples
|
||||||
- `make languages-list` - List all language directories
|
- `make languages-list` - List all language directories
|
||||||
|
|
|
||||||
14
languages/python/Dockerfile
Normal file
14
languages/python/Dockerfile
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY requirements.txt /app/requirements.txt
|
||||||
|
COPY examples.py /app/examples.py
|
||||||
|
|
||||||
|
RUN chmod +x /app/examples.py
|
||||||
|
|
||||||
|
RUN apk --no-cache add python3 py3-pip ca-certificates \
|
||||||
|
&& pip3 install --break-system-packages -r /app/requirements.txt \
|
||||||
|
&& rm -rf /var/cache/apk/*
|
||||||
|
|
||||||
|
CMD ["python3", "/app/examples.py"]
|
||||||
83
languages/python/examples.py
Normal file
83
languages/python/examples.py
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
uncloseai.com API Examples in Python
|
||||||
|
Demonstrates Hermes AI, Qwen Coder, and TTS endpoints
|
||||||
|
"""
|
||||||
|
|
||||||
|
from openai import OpenAI
|
||||||
|
|
||||||
|
print("=== uncloseai.com Python Examples ===")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Example 1: Hermes AI Chat (Non-Streaming)
|
||||||
|
print("1. Hermes AI - General Purpose Chat")
|
||||||
|
print(" Asking: 'Give a Python Fizzbuzz solution in one line of code?'")
|
||||||
|
print()
|
||||||
|
|
||||||
|
hermes_client = OpenAI(
|
||||||
|
base_url="https://hermes.ai.unturf.com/v1",
|
||||||
|
api_key="dummy-key"
|
||||||
|
)
|
||||||
|
|
||||||
|
hermes_response = hermes_client.chat.completions.create(
|
||||||
|
model="adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic",
|
||||||
|
messages=[{"role": "user", "content": "Give a Python Fizzbuzz solution in one line of code?"}],
|
||||||
|
temperature=0.5,
|
||||||
|
max_tokens=150
|
||||||
|
)
|
||||||
|
|
||||||
|
print("Response:")
|
||||||
|
print(hermes_response.choices[0].message.content)
|
||||||
|
print()
|
||||||
|
print("---")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Example 2: Qwen 3 Coder - Specialized Coding Model
|
||||||
|
print("2. Qwen 3 Coder - Specialized for Code")
|
||||||
|
print(" Asking: 'Write a Python function to validate an email address'")
|
||||||
|
print()
|
||||||
|
|
||||||
|
qwen_client = OpenAI(
|
||||||
|
base_url="https://qwen.ai.unturf.com/v1",
|
||||||
|
api_key="dummy-key"
|
||||||
|
)
|
||||||
|
|
||||||
|
qwen_response = qwen_client.chat.completions.create(
|
||||||
|
model="hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M",
|
||||||
|
messages=[{"role": "user", "content": "Write a Python function to validate an email address"}],
|
||||||
|
temperature=0.5,
|
||||||
|
max_tokens=200
|
||||||
|
)
|
||||||
|
|
||||||
|
print("Response:")
|
||||||
|
print(qwen_response.choices[0].message.content)
|
||||||
|
print()
|
||||||
|
print("---")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Example 3: Text-to-Speech
|
||||||
|
print("3. Text-to-Speech Generation")
|
||||||
|
print(" Converting text to speech and saving to speech.mp3")
|
||||||
|
print()
|
||||||
|
|
||||||
|
tts_client = OpenAI(
|
||||||
|
base_url="https://speech.ai.unturf.com/v1",
|
||||||
|
api_key="YOLO"
|
||||||
|
)
|
||||||
|
|
||||||
|
with tts_client.audio.speech.with_streaming_response.create(
|
||||||
|
model="tts-1",
|
||||||
|
voice="alloy",
|
||||||
|
input="Hello from Python! Today is a wonderful day to build something people love!"
|
||||||
|
) as response:
|
||||||
|
response.stream_to_file("speech.mp3")
|
||||||
|
|
||||||
|
import os
|
||||||
|
if os.path.exists("speech.mp3"):
|
||||||
|
file_size = os.path.getsize("speech.mp3")
|
||||||
|
print(f"✓ Speech file created: speech.mp3 ({file_size} bytes)")
|
||||||
|
else:
|
||||||
|
print("✗ Failed to create speech file")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("=== Examples Complete ===")
|
||||||
1
languages/python/requirements.txt
Normal file
1
languages/python/requirements.txt
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
openai==2.3.0
|
||||||
15
languages/zig/Dockerfile
Normal file
15
languages/zig/Dockerfile
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
FROM alpine:latest AS builder
|
||||||
|
|
||||||
|
RUN apk add --no-cache curl tar xz && \
|
||||||
|
curl -L https://ziglang.org/download/0.13.0/zig-linux-x86_64-0.13.0.tar.xz | tar -xJ && \
|
||||||
|
mv zig-linux-x86_64-0.13.0 /opt/zig
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
RUN /opt/zig/zig build -Doptimize=ReleaseSafe
|
||||||
|
|
||||||
|
FROM alpine:latest
|
||||||
|
RUN apk add --no-cache ca-certificates
|
||||||
|
COPY --from=builder /app/zig-out/bin/ai-examples /usr/local/bin/ai-examples
|
||||||
|
|
||||||
|
CMD ["ai-examples"]
|
||||||
25
languages/zig/build.zig
Normal file
25
languages/zig/build.zig
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "ai-examples",
|
||||||
|
.root_source_file = b.path("src/main.zig"),
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
b.installArtifact(exe);
|
||||||
|
|
||||||
|
const run_cmd = b.addRunArtifact(exe);
|
||||||
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
|
|
||||||
|
if (b.args) |args| {
|
||||||
|
run_cmd.addArgs(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
const run_step = b.step("run", "Run the app");
|
||||||
|
run_step.dependOn(&run_cmd.step);
|
||||||
|
}
|
||||||
154
languages/zig/src/main.zig
Normal file
154
languages/zig/src/main.zig
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const http = std.http;
|
||||||
|
const json = std.json;
|
||||||
|
|
||||||
|
// API Configuration
|
||||||
|
const HERMES_API_URL = "https://hermes.ai.unturf.com/v1/chat/completions";
|
||||||
|
const QWEN_API_URL = "https://qwen.ai.unturf.com/v1/chat/completions";
|
||||||
|
const TTS_API_URL = "https://speech.ai.unturf.com/v1/audio/speech";
|
||||||
|
const API_KEY = "dummy-api-key";
|
||||||
|
const HERMES_MODEL = "adamo1139/Hermes-3-Llama-3.1-8B-FP8-Dynamic";
|
||||||
|
const QWEN_MODEL = "hf.co/unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M";
|
||||||
|
|
||||||
|
// Chat completion request structure
|
||||||
|
const ChatMessage = struct {
|
||||||
|
role: []const u8,
|
||||||
|
content: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const ChatRequest = struct {
|
||||||
|
model: []const u8,
|
||||||
|
messages: []const ChatMessage,
|
||||||
|
max_tokens: u32 = 1000,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TTS request structure
|
||||||
|
const TTSRequest = struct {
|
||||||
|
model: []const u8,
|
||||||
|
voice: []const u8,
|
||||||
|
input: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn makeHTTPRequest(allocator: std.mem.Allocator, url: []const u8, json_payload: []const u8) ![]u8 {
|
||||||
|
const uri = try std.Uri.parse(url);
|
||||||
|
|
||||||
|
var client = http.Client{ .allocator = allocator };
|
||||||
|
defer client.deinit();
|
||||||
|
|
||||||
|
const server_header_buffer = try allocator.alloc(u8, 1024 * 8);
|
||||||
|
defer allocator.free(server_header_buffer);
|
||||||
|
|
||||||
|
var req = try client.open(.POST, uri, .{
|
||||||
|
.server_header_buffer = server_header_buffer,
|
||||||
|
.extra_headers = &[_]http.Header{
|
||||||
|
.{ .name = "Content-Type", .value = "application/json" },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
defer req.deinit();
|
||||||
|
|
||||||
|
req.transfer_encoding = .chunked;
|
||||||
|
|
||||||
|
try req.send();
|
||||||
|
try req.writeAll(json_payload);
|
||||||
|
try req.finish();
|
||||||
|
try req.wait();
|
||||||
|
|
||||||
|
const body = try req.reader().readAllAlloc(allocator, 1024 * 1024 * 10);
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hermesExample(allocator: std.mem.Allocator) !void {
|
||||||
|
std.debug.print("\n=== Hermes AI Chat Example ===\n", .{});
|
||||||
|
|
||||||
|
const messages = [_]ChatMessage{
|
||||||
|
.{ .role = "system", .content = "You are Hermes, a helpful AI assistant from Nous Research." },
|
||||||
|
.{ .role = "user", .content = "Explain quantum computing in one sentence." },
|
||||||
|
};
|
||||||
|
|
||||||
|
const request = ChatRequest{
|
||||||
|
.model = HERMES_MODEL,
|
||||||
|
.messages = &messages,
|
||||||
|
.max_tokens = 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
const json_string = try json.stringifyAlloc(allocator, request, .{});
|
||||||
|
defer allocator.free(json_string);
|
||||||
|
|
||||||
|
std.debug.print("Request: {s}\n", .{json_string});
|
||||||
|
|
||||||
|
const response = try makeHTTPRequest(allocator, HERMES_API_URL, json_string);
|
||||||
|
defer allocator.free(response);
|
||||||
|
|
||||||
|
std.debug.print("Response: {s}\n", .{response});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn qwenExample(allocator: std.mem.Allocator) !void {
|
||||||
|
std.debug.print("\n=== Qwen Coder Example ===\n", .{});
|
||||||
|
|
||||||
|
const messages = [_]ChatMessage{
|
||||||
|
.{ .role = "system", .content = "You are Qwen, a coding assistant specialized in software development." },
|
||||||
|
.{ .role = "user", .content = "Write a hello world function in Python." },
|
||||||
|
};
|
||||||
|
|
||||||
|
const request = ChatRequest{
|
||||||
|
.model = QWEN_MODEL,
|
||||||
|
.messages = &messages,
|
||||||
|
.max_tokens = 200,
|
||||||
|
};
|
||||||
|
|
||||||
|
const json_string = try json.stringifyAlloc(allocator, request, .{});
|
||||||
|
defer allocator.free(json_string);
|
||||||
|
|
||||||
|
std.debug.print("Request: {s}\n", .{json_string});
|
||||||
|
|
||||||
|
const response = try makeHTTPRequest(allocator, QWEN_API_URL, json_string);
|
||||||
|
defer allocator.free(response);
|
||||||
|
|
||||||
|
std.debug.print("Response: {s}\n", .{response});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ttsExample(allocator: std.mem.Allocator) !void {
|
||||||
|
std.debug.print("\n=== TTS Speech Generation Example ===\n", .{});
|
||||||
|
|
||||||
|
const request = TTSRequest{
|
||||||
|
.model = "tts-1",
|
||||||
|
.voice = "alloy",
|
||||||
|
.input = "Hello from Zig! This is a text to speech example.",
|
||||||
|
};
|
||||||
|
|
||||||
|
const json_string = try json.stringifyAlloc(allocator, request, .{});
|
||||||
|
defer allocator.free(json_string);
|
||||||
|
|
||||||
|
std.debug.print("Request: {s}\n", .{json_string});
|
||||||
|
|
||||||
|
const response = try makeHTTPRequest(allocator, TTS_API_URL, json_string);
|
||||||
|
defer allocator.free(response);
|
||||||
|
|
||||||
|
// Save audio to file
|
||||||
|
const file = try std.fs.cwd().createFile("output.mp3", .{});
|
||||||
|
defer file.close();
|
||||||
|
try file.writeAll(response);
|
||||||
|
|
||||||
|
std.debug.print("Audio saved to output.mp3 ({} bytes)\n", .{response.len});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
|
||||||
|
std.debug.print("Zig AI API Examples\n", .{});
|
||||||
|
std.debug.print("====================\n", .{});
|
||||||
|
|
||||||
|
hermesExample(allocator) catch |err| {
|
||||||
|
std.debug.print("Hermes example failed: {}\n", .{err});
|
||||||
|
};
|
||||||
|
|
||||||
|
qwenExample(allocator) catch |err| {
|
||||||
|
std.debug.print("Qwen example failed: {}\n", .{err});
|
||||||
|
};
|
||||||
|
|
||||||
|
ttsExample(allocator) catch |err| {
|
||||||
|
std.debug.print("TTS example failed: {}\n", .{err});
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue