From 4941cce333c324cc663cb285ab56208cc250c905 Mon Sep 17 00:00:00 2001 From: Russell Ballestrini Date: Sun, 12 Oct 2025 15:17:12 -0400 Subject: [PATCH] reorganize Python with openai-client and requests subdirs, pin to python:3.13-alpine, add Docker image consistency standards --- CLAUDE.md | 22 ++++ languages/python/Dockerfile | 14 --- languages/python/openai-client/Dockerfile | 13 +++ .../python/{ => openai-client}/examples.py | 0 .../{ => openai-client}/requirements.txt | 0 languages/python/requests/Dockerfile | 13 +++ languages/python/requests/examples.py | 100 ++++++++++++++++++ languages/python/requests/requirements.txt | 2 + 8 files changed, 150 insertions(+), 14 deletions(-) delete mode 100644 languages/python/Dockerfile create mode 100644 languages/python/openai-client/Dockerfile rename languages/python/{ => openai-client}/examples.py (100%) rename languages/python/{ => openai-client}/requirements.txt (100%) create mode 100644 languages/python/requests/Dockerfile create mode 100644 languages/python/requests/examples.py create mode 100644 languages/python/requests/requirements.txt diff --git a/CLAUDE.md b/CLAUDE.md index c500c2a..ef245e0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -197,6 +197,28 @@ openai==2.3.0 ❌ openai~=1.0 (lazy, not latest) ``` +## Docker Base Image Standards +**CRITICAL: Use consistent, pinned base images within each language** + +1. **All examples for a language MUST use the same base image** + - ✅ All Python examples use `python:3.13-alpine` + - ✅ All Node.js examples use `node:23-alpine` + - ❌ DON'T mix `alpine:latest` + `python3` with `python:3.13-alpine` + +2. **Pin to specific versions, document check date** + ```dockerfile + # Pin to specific Python version (checked 2025-10-12: python:3.13-alpine is latest stable) + FROM python:3.13-alpine + ``` + +3. **Prefer official language images over generic + manual install** + - ✅ `FROM python:3.13-alpine` (official, clean) + - ❌ `FROM alpine:latest` + `RUN apk add python3` (messy, inconsistent) + +4. **Use alpine variants for smaller images** + - `python:3.13-alpine` not `python:3.13` + - `node:23-alpine` not `node:23` + ## Makefile Commands for Language Examples - `make languages-list` - List all language directories - `make languages-build-{lang}` - Build Docker image for specific language diff --git a/languages/python/Dockerfile b/languages/python/Dockerfile deleted file mode 100644 index f66a386..0000000 --- a/languages/python/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -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/openai-client/Dockerfile b/languages/python/openai-client/Dockerfile new file mode 100644 index 0000000..5019f0d --- /dev/null +++ b/languages/python/openai-client/Dockerfile @@ -0,0 +1,13 @@ +# Pin to specific Python version (checked 2025-10-12: python:3.13-alpine is latest stable) +FROM python:3.13-alpine + +WORKDIR /app + +COPY requirements.txt /app/requirements.txt +COPY examples.py /app/examples.py + +RUN chmod +x /app/examples.py + +RUN pip3 install --no-cache-dir -r /app/requirements.txt + +CMD ["python3", "/app/examples.py"] diff --git a/languages/python/examples.py b/languages/python/openai-client/examples.py similarity index 100% rename from languages/python/examples.py rename to languages/python/openai-client/examples.py diff --git a/languages/python/requirements.txt b/languages/python/openai-client/requirements.txt similarity index 100% rename from languages/python/requirements.txt rename to languages/python/openai-client/requirements.txt diff --git a/languages/python/requests/Dockerfile b/languages/python/requests/Dockerfile new file mode 100644 index 0000000..5019f0d --- /dev/null +++ b/languages/python/requests/Dockerfile @@ -0,0 +1,13 @@ +# Pin to specific Python version (checked 2025-10-12: python:3.13-alpine is latest stable) +FROM python:3.13-alpine + +WORKDIR /app + +COPY requirements.txt /app/requirements.txt +COPY examples.py /app/examples.py + +RUN chmod +x /app/examples.py + +RUN pip3 install --no-cache-dir -r /app/requirements.txt + +CMD ["python3", "/app/examples.py"] diff --git a/languages/python/requests/examples.py b/languages/python/requests/examples.py new file mode 100644 index 0000000..8a79740 --- /dev/null +++ b/languages/python/requests/examples.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +""" +uncloseai.com API Examples in Python using requests library +Demonstrates direct HTTP calls to Hermes AI, Qwen Coder, and TTS endpoints +""" + +import requests +import json + +print("=== uncloseai.com Python (requests) Examples ===") +print() + +# Example 1: Hermes AI Chat using requests +print("1. Hermes AI - General Purpose Chat (using requests)") +print(" Asking: 'Give a Python Fizzbuzz solution in one line of code?'") +print() + +hermes_response = requests.post( + "https://hermes.ai.unturf.com/v1/chat/completions", + headers={ + "Content-Type": "application/json", + "Authorization": "Bearer dummy-key" + }, + json={ + "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 + } +) + +if hermes_response.status_code == 200: + print("Response:") + print(hermes_response.json()["choices"][0]["message"]["content"]) +else: + print(f"Error: {hermes_response.status_code} - {hermes_response.text}") + +print() +print("---") +print() + +# Example 2: Qwen 3 Coder using requests +print("2. Qwen 3 Coder - Specialized for Code (using requests)") +print(" Asking: 'Write a Python function to validate an email address'") +print() + +qwen_response = requests.post( + "https://qwen.ai.unturf.com/v1/chat/completions", + headers={ + "Content-Type": "application/json", + "Authorization": "Bearer dummy-key" + }, + json={ + "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 + } +) + +if qwen_response.status_code == 200: + print("Response:") + print(qwen_response.json()["choices"][0]["message"]["content"]) +else: + print(f"Error: {qwen_response.status_code} - {qwen_response.text}") + +print() +print("---") +print() + +# Example 3: Text-to-Speech using requests +print("3. Text-to-Speech Generation (using requests)") +print(" Converting text to speech and saving to speech.mp3") +print() + +tts_response = requests.post( + "https://speech.ai.unturf.com/v1/audio/speech", + headers={ + "Content-Type": "application/json", + "Authorization": "Bearer YOLO" + }, + json={ + "model": "tts-1", + "voice": "alloy", + "input": "Hello from Python using requests! Today is a wonderful day to build something people love!" + } +) + +if tts_response.status_code == 200: + with open("speech.mp3", "wb") as f: + f.write(tts_response.content) + + import os + file_size = os.path.getsize("speech.mp3") + print(f"✓ Speech file created: speech.mp3 ({file_size} bytes)") +else: + print(f"✗ Failed to create speech file: {tts_response.status_code}") + +print() +print("=== Examples Complete ===") diff --git a/languages/python/requests/requirements.txt b/languages/python/requests/requirements.txt new file mode 100644 index 0000000..8b4032c --- /dev/null +++ b/languages/python/requests/requirements.txt @@ -0,0 +1,2 @@ +# Python HTTP library (checked 2025-10-12) +requests==2.32.5