134 lines
3.6 KiB
Python
134 lines
3.6 KiB
Python
import base64
|
|
import os
|
|
from datetime import datetime
|
|
from io import BytesIO
|
|
|
|
import requests
|
|
from PIL import Image
|
|
|
|
# Configuration
|
|
BASE_URL = "https://llama-cpp.reeselink.com"
|
|
API_KEY = os.getenv("LLAMA_CPP_API_KEY", "") # Set if required
|
|
|
|
|
|
def call_api(endpoint, method="GET", data=None):
|
|
"""Generic API call helper"""
|
|
url = f"{BASE_URL}/v1/{endpoint}"
|
|
headers = {"Content-Type": "application/json"}
|
|
if API_KEY:
|
|
headers["Authorization"] = f"Bearer {API_KEY}"
|
|
|
|
response = requests.request(method, url, headers=headers, json=data)
|
|
return response
|
|
|
|
|
|
# 1. List Models
|
|
models_response = call_api("models")
|
|
models = models_response.json().get("data", [])
|
|
print(f"Available models: {[m['id'] for m in models]}")
|
|
|
|
# 2. Use First Model
|
|
model_id = models[1]["id"]
|
|
|
|
# 3. Chat Completion
|
|
chat_data = {
|
|
"model": model_id,
|
|
"messages": [
|
|
{"role": "system", "content": "You are helpful."},
|
|
{"role": "user", "content": "Tell me about Everquest!"},
|
|
],
|
|
"temperature": 0.95,
|
|
"max_tokens": 100,
|
|
}
|
|
response = call_api("chat/completions", "POST", chat_data)
|
|
print(response.json()["choices"][0]["message"]["content"])
|
|
|
|
|
|
def describe_image(image_path, api_key=None):
|
|
"""
|
|
Send an image to the LLM for description
|
|
"""
|
|
base_url = "https://llama-cpp.reeselink.com"
|
|
|
|
# Read and encode image to base64
|
|
with open(image_path, "rb") as f:
|
|
encoded_image = base64.b64encode(f.read()).decode("utf-8")
|
|
|
|
# Prepare headers
|
|
headers = {"Content-Type": "application/json"}
|
|
if api_key:
|
|
headers["Authorization"] = f"Bearer {api_key}"
|
|
|
|
# Create payload
|
|
payload = {
|
|
"model": "qwen3-vl-30b-a3b-instruct", # 👁️ VISION MODEL
|
|
"messages": [
|
|
{
|
|
"role": "user",
|
|
"content": [
|
|
{"type": "text", "text": "Describe this image in detail"},
|
|
{
|
|
"type": "image_url",
|
|
"image_url": {"url": f"data:image/jpeg;base64,{encoded_image}"},
|
|
},
|
|
],
|
|
}
|
|
],
|
|
"max_tokens": 1000,
|
|
"temperature": 0.7,
|
|
}
|
|
|
|
# Send request
|
|
response = requests.post(
|
|
f"{base_url}/v1/chat/completions", headers=headers, json=payload
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
return response.json()["choices"][0]["message"]["content"]
|
|
else:
|
|
print(f"Error: {response.status_code}")
|
|
print(response.text)
|
|
return None
|
|
|
|
|
|
# description = describe_image("generated-image.png", api_key="your_key")
|
|
# print(description)
|
|
|
|
|
|
def generate_image(prompt, **kwargs):
|
|
"""
|
|
Generate image using Stable Diffusion / OpenAI compatible API
|
|
"""
|
|
base_url = "http://toybox.reeselink.com:1234/v1"
|
|
|
|
payload = {"model": "default", "prompt": prompt, "n": 1, "size": "1024x1024"}
|
|
|
|
response = requests.post(
|
|
f"http://toybox.reeselink.com:1234/v1/images/generations",
|
|
json=payload,
|
|
timeout=120,
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
result = response.json()
|
|
# Save image
|
|
image_data = base64.b64decode(result["data"][0]["b64_json"])
|
|
img = Image.open(BytesIO(image_data))
|
|
filename = f"generated_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
|
|
img.save(filename)
|
|
print(f"✅ Saved: {filename}")
|
|
return result
|
|
else:
|
|
print(f"❌ Error: {response.status_code}")
|
|
print(response.text)
|
|
return None
|
|
|
|
|
|
# Usage:
|
|
result = generate_image(
|
|
prompt="A beautiful sunset over mountains, photorealistic",
|
|
negative_prompt="blurry, low quality",
|
|
steps=8,
|
|
guidance=7.5,
|
|
)
|