vitaai · Python SDK
Python SDK for VitaAI self-hosted LLM endpoints.
Works just like the Google Gemini SDK — client.models.method() pattern with a stream parameter on every endpoint.
Install
pip install vitaai
pip install requests # required for image endpoints
Quick start
from vitaai import VitaAI
client = VitaAI(
base_url="http://your-server-ip:8000",
api_key="your-api-key" # optional — not required if server has no auth
)
response = client.models.generate_content(
model="gemma-4-E2B-it",
contents="What is AI?",
max_output_tokens=100
)
print(response.text)
print("Tokens:", response.usage_metadata.total_token_count)
Client parameters
| Parameter |
Type |
Default |
Description |
base_url |
str |
https://api.vitaai-api.com |
Your self-hosted server URL |
api_key |
str |
None |
Optional API key. Or set VITAAI_API_KEY env var |
timeout |
int |
120 |
Request timeout in seconds |
Streaming
Every endpoint supports a stream parameter:
stream=False (default) — waits and returns the full response object
stream=True — yields tokens live as the model generates them
# Normal — full response at once
r = client.models.generate_content(model="gemma-4-E2B-it", contents="What is AI?")
print(r.text)
# Streaming — tokens print live
for chunk in client.models.generate_content(model="gemma-4-E2B-it", contents="What is AI?", stream=True):
print(chunk.text, end="", flush=True)
Endpoints
1. Generate content
r = client.models.generate_content(
model="gemma-4-E2B-it",
contents="What is machine learning?",
max_output_tokens=150,
stream=False, # default
)
print(r.text)
print("Tokens:", r.usage_metadata.total_token_count)
With config (system instruction, temperature, etc.)
r = client.models.generate_content(
model="gemma-4-E2B-it",
contents="Explain deep learning",
config={
"system_instruction": "You are a teacher. Explain simply.",
"temperature": 0.7,
"top_p": 0.9,
"max_output_tokens": 200,
}
)
print(r.text)
Multi-turn conversation
r = client.models.generate_content(
model="gemma-4-E2B-it",
contents=[
{"role": "user", "parts": [{"text": "My name is Alex."}]},
{"role": "model", "parts": [{"text": "Nice to meet you, Alex!"}]},
{"role": "user", "parts": [{"text": "What is my name?"}]},
]
)
print(r.text)
Streaming
for chunk in client.models.generate_content(
model="gemma-4-E2B-it",
contents="Write a short poem.",
max_output_tokens=100,
stream=True,
):
print(chunk.text, end="", flush=True)
| Response field |
Type |
Description |
r.text |
str |
Full generated text |
r.usage_metadata.prompt_token_count |
int |
Input tokens |
r.usage_metadata.candidates_token_count |
int |
Output tokens |
r.usage_metadata.total_token_count |
int |
Total tokens |
2. Summarize
# Normal
r = client.models.summarize(
contents="Long article text here...",
format="bullets", # "paragraph" or "bullets"
max_output_tokens=150,
)
print(r.summary)
# Streaming
for chunk in client.models.summarize(contents="Long article...", format="paragraph", stream=True):
print(chunk.text, end="", flush=True)
| Parameter |
Type |
Default |
Description |
contents |
str |
— |
Text to summarize |
format |
str |
"paragraph" |
"paragraph" or "bullets" |
max_output_tokens |
int |
200 |
Max summary length |
stream |
bool |
False |
Stream tokens live |
| Response field |
Type |
Description |
r.summary |
str |
Summarized text |
r.format |
str |
Format used |
r.usage_metadata.total_token_count |
int |
Total tokens |
3. Embeddings
r = client.models.embed_content(
contents="Artificial intelligence is transforming the world."
)
print("Dimensions:", len(r.embedding.values))
print("Vector:", r.embedding.values[:5])
| Response field |
Type |
Description |
r.embedding.values |
List[float] |
The embedding vector |
4. Analyze image
# Normal
r = client.models.analyze_image(
file_path="photo.jpg",
prompt="What objects are visible in this image?",
max_output_tokens=512,
)
print(r.analysis)
# Streaming
for chunk in client.models.analyze_image(file_path="photo.jpg", prompt="What do you see?", stream=True):
print(chunk.text, end="", flush=True)
| Parameter |
Type |
Default |
Description |
file_path |
str |
— |
Path to image (JPG, PNG, WEBP, GIF) |
prompt |
str |
— |
Question or instruction |
system_instruction |
str |
None |
Optional system prompt |
temperature |
float |
1.0 |
Sampling temperature |
max_output_tokens |
int |
512 |
Max response length |
image_token_budget |
int |
280 |
Detail level: 70/140/280/560/1120 |
stream |
bool |
False |
Stream tokens live |
| Response field |
Type |
Description |
r.analysis |
str |
Model's analysis |
r.image_info.size |
tuple |
Image dimensions |
r.usage_metadata.total_token_count |
int |
Total tokens |
5. Describe image
# Normal
r = client.models.describe_image(file_path="photo.jpg", max_output_tokens=512)
print(r.description)
# Streaming
for chunk in client.models.describe_image(file_path="photo.jpg", stream=True):
print(chunk.text, end="", flush=True)
| Response field |
Type |
Description |
r.description |
str |
Full image description |
r.image_info.size |
tuple |
Image dimensions |
r.usage_metadata.total_token_count |
int |
Total tokens |
6. OCR — extract text from image
# Normal
r = client.models.ocr_image(file_path="document.png", language="English")
print(r.extracted_text)
# Streaming
for chunk in client.models.ocr_image(file_path="document.png", stream=True):
print(chunk.text, end="", flush=True)
| Parameter |
Type |
Default |
Description |
file_path |
str |
— |
Path to image |
language |
str |
"English" |
Language of text in image |
max_output_tokens |
int |
512 |
Max response length |
image_token_budget |
int |
560 |
Higher = better OCR accuracy |
stream |
bool |
False |
Stream tokens live |
| Response field |
Type |
Description |
r.extracted_text |
str |
All text found in image |
r.image_info.language |
str |
Language used |
r.usage_metadata.total_token_count |
int |
Total tokens |
7. Ping
r = client.models.ping()
print(r.status) # "ok"
print(r.model) # "gemma-4-E2B-it"
print(r.device) # "CUDA"
print(r.version) # "2.3.0"
print(r.limits.max_input_tokens)
print(r.limits.max_output_tokens)
8. Health
r = client.models.health()
print(r.status) # "healthy"
print(r.cuda_available) # True / False
print(r.limits.max_input_tokens)
print(r.limits.max_output_tokens)
9. Stats
s = client.models.stats()
print(s.device) # "CUDA"
print(s.gpu_name) # "Tesla T4"
print(f"{s.gpu_memory_total_gb:.1f} GB")
print(f"{s.gpu_memory_allocated_gb:.1f} GB")
10. List models
for m in client.models.list():
print(m["name"])
print(m["capabilities"])
print(m["max_output_tokens"])
Error handling
from vitaai.transport import AuthenticationError, ServerError, VitaAIError
try:
r = client.models.generate_content(model="gemma-4-E2B-it", contents="Hello")
print(r.text)
except AuthenticationError:
print("Invalid API key")
except ServerError as e:
print(f"Server error ({e.status_code}): {e}")
except VitaAIError as e:
print(f"Error: {e}")
Server endpoints
| Method |
Path |
stream support |
| GET |
/ |
— |
| GET |
/health |
— |
| GET |
/v1/stats |
— |
| GET |
/v1/models/list |
— |
| POST |
/v1/models/generate |
✅ ?stream=true |
| POST |
/v1/models/summarize |
✅ ?stream=true |
| POST |
/v1/models/embed |
— |
| POST |
/v1/models/analyze-image |
✅ ?stream=true |
| POST |
/v1/models/describe-image |
✅ ?stream=true |
| POST |
/v1/models/ocr-image |
✅ ?stream=true |
Environment variables
| Variable |
Description |
VITAAI_API_KEY |
API key (alternative to api_key= parameter) |
VITAAI_BASE_URL |
Server URL (alternative to base_url= parameter) |