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
|
||||
- ✅ DOCUMENT our specific implementation choices
|
||||
- ✅ PROVIDE troubleshooting for this language
|
||||
- ✅ ALWAYS pin to LATEST version of dependencies (check pip/npm/etc for current version)
|
||||
- ❌ NO general programming tutorials
|
||||
- ❌ 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
|
||||
- `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