From 39502bcac35edee99b856a8f0ddc87f97bd85065 Mon Sep 17 00:00:00 2001 From: Russell Ballestrini Date: Sun, 12 Oct 2025 15:10:07 -0400 Subject: [PATCH] add Python example with openai==2.3.0 (latest) and dependency pinning standards to CLAUDE.md --- CLAUDE.md | 28 ++++++ languages/python/Dockerfile | 14 +++ languages/python/examples.py | 83 ++++++++++++++++ languages/python/requirements.txt | 1 + languages/zig/Dockerfile | 15 +++ languages/zig/build.zig | 25 +++++ languages/zig/src/main.zig | 154 ++++++++++++++++++++++++++++++ 7 files changed, 320 insertions(+) create mode 100644 languages/python/Dockerfile create mode 100644 languages/python/examples.py create mode 100644 languages/python/requirements.txt create mode 100644 languages/zig/Dockerfile create mode 100644 languages/zig/build.zig create mode 100644 languages/zig/src/main.zig diff --git a/CLAUDE.md b/CLAUDE.md index 898147f..c500c2a 100644 --- a/CLAUDE.md +++ b/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 diff --git a/languages/python/Dockerfile b/languages/python/Dockerfile new file mode 100644 index 0000000..f66a386 --- /dev/null +++ b/languages/python/Dockerfile @@ -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"] diff --git a/languages/python/examples.py b/languages/python/examples.py new file mode 100644 index 0000000..690858d --- /dev/null +++ b/languages/python/examples.py @@ -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 ===") diff --git a/languages/python/requirements.txt b/languages/python/requirements.txt new file mode 100644 index 0000000..f429274 --- /dev/null +++ b/languages/python/requirements.txt @@ -0,0 +1 @@ +openai==2.3.0 diff --git a/languages/zig/Dockerfile b/languages/zig/Dockerfile new file mode 100644 index 0000000..b81cc12 --- /dev/null +++ b/languages/zig/Dockerfile @@ -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"] diff --git a/languages/zig/build.zig b/languages/zig/build.zig new file mode 100644 index 0000000..efb7423 --- /dev/null +++ b/languages/zig/build.zig @@ -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); +} diff --git a/languages/zig/src/main.zig b/languages/zig/src/main.zig new file mode 100644 index 0000000..60d6e63 --- /dev/null +++ b/languages/zig/src/main.zig @@ -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}); + }; +}